// Created on: 1990-12-11 // Created by: Remi Lequette // Copyright (c) 1990-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _TopoDS_Shape_HeaderFile #define _TopoDS_Shape_HeaderFile #include "Standard_Handle.hxx" #include "TopLoc_Location.hxx" #include "TopoDS_TShape.hxx" #include "Standard_HashUtils.hxx" // resolve name collisions with X11 headers #ifdef Convex #undef Convex #endif //! Describes a shape which //! - references an underlying shape with the potential //! to be given a location and an orientation //! - has a location for the underlying shape, giving its //! placement in the local coordinate system //! - has an orientation for the underlying shape, in //! terms of its geometry (as opposed to orientation in //! relation to other shapes). //! Note: A Shape is empty if it references an underlying //! shape which has an empty list of shapes. class TopoDS_Shape { public: DEFINE_STANDARD_ALLOC //! Creates a NULL Shape referring to nothing. TopoDS_Shape() : myOrient(TopAbs_EXTERNAL) { } //! Generalized move constructor, accepting also sub-classes //! (TopoDS_Shape hierarchy declares only fake sub-classes with no extra fields). template TopoDS_Shape( T2&& theOther, typename std::enable_if::value>::type* = nullptr) : myTShape(std::forward(theOther).myTShape), myLocation(std::forward(theOther).myLocation), myOrient(std::forward(theOther).myOrient) { } //! Generalized move assignment operator. template typename std::enable_if::value, TopoDS_Shape>::type& operator=(T2&& theOther) { myTShape = std::forward(theOther).myTShape; myLocation = std::forward(theOther).myLocation; myOrient = std::forward(theOther).myOrient; return *this; } //! Returns true if this shape is null. In other words, it //! references no underlying shape with the potential to //! be given a location and an orientation. bool IsNull() const { return myTShape.IsNull(); } //! Destroys the reference to the underlying shape //! stored in this shape. As a result, this shape becomes null. void Nullify() { myTShape.Nullify(); myLocation.Clear(); myOrient = TopAbs_EXTERNAL; } //! Returns the shape local coordinate system. const TopLoc_Location& Location() const { return myLocation; } //! Sets the shape local coordinate system. //! @param theLoc the new local coordinate system. //! @param theRaiseExc flag to raise exception in case of transformation with scale or negative. void Location(const TopLoc_Location& theLoc, const bool theRaiseExc = false) { const gp_Trsf& aTrsf = theLoc.Transformation(); if (theRaiseExc) { validateTransformation(aTrsf); } myLocation = theLoc; } //! Returns a shape similar to with the local //! coordinate system set to . //! @param theLoc the new local coordinate system. //! @param theRaiseExc flag to raise exception in case of transformation with scale or negative. //! @return the located shape. TopoDS_Shape Located(const TopLoc_Location& theLoc, const bool theRaiseExc = false) const { TopoDS_Shape aShape(*this); aShape.Location(theLoc, theRaiseExc); return aShape; } //! Returns the shape orientation. TopAbs_Orientation Orientation() const { return myOrient; } //! Sets the shape orientation. void Orientation(TopAbs_Orientation theOrient) { myOrient = theOrient; } //! Returns a shape similar to with the //! orientation set to . TopoDS_Shape Oriented(TopAbs_Orientation theOrient) const { TopoDS_Shape aShape(*this); aShape.Orientation(theOrient); return aShape; } //! Returns a handle to the actual shape implementation. const occ::handle& TShape() const { return myTShape; } //! Returns the value of the TopAbs_ShapeEnum //! enumeration that corresponds to this shape, for //! example VERTEX, EDGE, and so on. //! Exceptions //! Standard_NullObject if this shape is null. TopAbs_ShapeEnum ShapeType() const { return myTShape->ShapeType(); } //! Returns the free flag. bool Free() const { return myTShape->Free(); } //! Sets the free flag. void Free(bool theIsFree) { myTShape->Free(theIsFree); } //! Returns the locked flag. bool Locked() const { return myTShape->Locked(); } //! Sets the locked flag. void Locked(bool theIsLocked) { myTShape->Locked(theIsLocked); } //! Returns the modification flag. bool Modified() const { return myTShape->Modified(); } //! Sets the modification flag. void Modified(bool theIsModified) { myTShape->Modified(theIsModified); } //! Returns the checked flag. bool Checked() const { return myTShape->Checked(); } //! Sets the checked flag. void Checked(bool theIsChecked) { myTShape->Checked(theIsChecked); } //! Returns the orientability flag. bool Orientable() const { return myTShape->Orientable(); } //! Sets the orientability flag. void Orientable(const bool theIsOrientable) { myTShape->Orientable(theIsOrientable); } //! Returns the closedness flag. bool Closed() const { return myTShape->Closed(); } //! Sets the closedness flag. void Closed(bool theIsClosed) { myTShape->Closed(theIsClosed); } //! Returns the infinity flag. bool Infinite() const { return myTShape->Infinite(); } //! Sets the infinity flag. void Infinite(bool theIsInfinite) { myTShape->Infinite(theIsInfinite); } //! Returns the convexness flag. bool Convex() const { return myTShape->Convex(); } //! Sets the convexness flag. void Convex(bool theIsConvex) { myTShape->Convex(theIsConvex); } //! Multiplies the Shape location by thePosition. //! @param thePosition the transformation to apply. //! @param theRaiseExc flag to raise exception in case of transformation with scale or negative. void Move(const TopLoc_Location& thePosition, const bool theRaiseExc = false) { const gp_Trsf& aTrsf = thePosition.Transformation(); if (theRaiseExc) { validateTransformation(aTrsf); } myLocation = thePosition * myLocation; } //! Returns a shape similar to with a location multiplied by thePosition. //! @param thePosition the transformation to apply. //! @param theRaiseExc flag to raise exception in case of transformation with scale or negative. //! @return the moved shape. TopoDS_Shape Moved(const TopLoc_Location& thePosition, const bool theRaiseExc = false) const { TopoDS_Shape aShape(*this); aShape.Move(thePosition, theRaiseExc); return aShape; } //! Reverses the orientation, using the Reverse method //! from the TopAbs package. void Reverse() { myOrient = TopAbs::Reverse(myOrient); } //! Returns a shape similar to with the //! orientation reversed, using the Reverse method //! from the TopAbs package. TopoDS_Shape Reversed() const { TopoDS_Shape aShape(*this); aShape.Reverse(); return aShape; } //! Complements the orientation, using the Complement //! method from the TopAbs package. void Complement() { myOrient = TopAbs::Complement(myOrient); } //! Returns a shape similar to with the //! orientation complemented, using the Complement //! method from the TopAbs package. TopoDS_Shape Complemented() const { TopoDS_Shape aShape(*this); aShape.Complement(); return aShape; } //! Updates the Shape Orientation by composition with theOrient, //! using the Compose method from the TopAbs package. void Compose(TopAbs_Orientation theOrient) { myOrient = TopAbs::Compose(myOrient, theOrient); } //! Returns a shape similar to with the //! orientation composed with theOrient, using the //! Compose method from the TopAbs package. TopoDS_Shape Composed(TopAbs_Orientation theOrient) const { TopoDS_Shape aShape(*this); aShape.Compose(theOrient); return aShape; } //! Returns the number of direct sub-shapes (children). //! @sa TopoDS_Iterator for accessing sub-shapes int NbChildren() const { return myTShape.IsNull() ? 0 : myTShape->NbChildren(); } //! Returns True if two shapes are partners, i.e. if //! they share the same TShape. Locations and //! Orientations may differ. bool IsPartner(const TopoDS_Shape& theOther) const { return (myTShape == theOther.myTShape); } //! Returns True if two shapes are same, i.e. if they //! share the same TShape with the same Locations. //! Orientations may differ. bool IsSame(const TopoDS_Shape& theOther) const { return myTShape == theOther.myTShape && myLocation == theOther.myLocation; } //! Returns True if two shapes are equal, i.e. if they //! share the same TShape with the same Locations and //! Orientations. bool IsEqual(const TopoDS_Shape& theOther) const { return myTShape == theOther.myTShape && myLocation == theOther.myLocation && myOrient == theOther.myOrient; } bool operator==(const TopoDS_Shape& theOther) const { return IsEqual(theOther); } //! Negation of the IsEqual method. bool IsNotEqual(const TopoDS_Shape& theOther) const { return !IsEqual(theOther); } bool operator!=(const TopoDS_Shape& theOther) const { return IsNotEqual(theOther); } //! Replace by a new Shape with the same //! Orientation and Location and a new TShape with the //! same geometry and no sub-shapes. void EmptyCopy() { myTShape = myTShape->EmptyCopy(); } //! Returns a new Shape with the same Orientation and //! Location and a new TShape with the same geometry //! and no sub-shapes. TopoDS_Shape EmptyCopied() const { TopoDS_Shape aShape(*this); aShape.EmptyCopy(); return aShape; } void TShape(const occ::handle& theTShape) { myTShape = theTShape; } //! Dumps the content of me into the stream Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const; protected: //! Checks if the transformation contains scaling or negative values. //! Raises an exception if the transformation is invalid. //! @param theTrsf transformation to validate void validateTransformation(const gp_Trsf& theTrsf) const { if (std::abs(std::abs(theTrsf.ScaleFactor()) - 1.) > TopLoc_Location::ScalePrec() || theTrsf.IsNegative()) { // Exception throw Standard_DomainError("Transformation with scaling transformation is forbidden"); } } private: occ::handle myTShape; TopLoc_Location myLocation; TopAbs_Orientation myOrient; }; namespace std { template <> struct hash { size_t operator()(const TopoDS_Shape& theShape) const noexcept { const size_t aHL = std::hash{}(theShape.Location()); return aHL == 0 ? opencascade::hash(theShape.TShape().get()) : opencascade::MurmurHash::hash_combine(theShape.TShape().get(), sizeof(void*), aHL); } }; } // namespace std #endif // _TopoDS_Shape_HeaderFile