#include <GeomAPI_Wire.h>
#include <Bnd_Box.hxx>
-#include <BOPTools.hxx>
#include <BRep_Builder.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAlgo.hxx>
#include <Geom2d_Curve.hxx>
#include <BRepLib_CheckCurveOnSurface.hxx>
#include <BRep_Tool.hxx>
+#include <Geom_CylindricalSurface.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_ShapeIterator.h>
#include <GeomLib_IsPlanarSurface.hxx>
#include <GeomLib_Tool.hxx>
#include <GeomAPI_IntCS.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS_Edge.hxx>
+//==================================================================================================
+static GProp_GProps props(const TopoDS_Shape& theShape)
+{
+ GProp_GProps aGProps;
+
+ if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
+ {
+ BRepGProp::LinearProperties(theShape, aGProps);
+ }
+ else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
+ {
+ const Standard_Real anEps = 1.e-6;
+ BRepGProp::SurfaceProperties(theShape, aGProps, anEps);
+ }
+ else if (theShape.ShapeType() == TopAbs_SOLID || theShape.ShapeType() == TopAbs_COMPSOLID)
+ {
+ BRepGProp::VolumeProperties(theShape, aGProps);
+ }
+ else if (theShape.ShapeType() == TopAbs_COMPOUND)
+ {
+ for (TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next())
+ {
+ aGProps.Add(props(anIt.Value()));
+ }
+ }
+
+ return aGProps;
+}
+
//==================================================================================================
double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
{
gp_Pnt aCentre;
if(aShape.ShapeType() == TopAbs_VERTEX) {
aCentre = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
- } else if(aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) {
- BRepGProp::LinearProperties(aShape, aGProps);
- aCentre = aGProps.CentreOfMass();
} else {
- const Standard_Real anEps = 1.e-6;
- BRepGProp::SurfaceProperties(aShape, aGProps, anEps);
+ aGProps = props(aShape);
aCentre = aGProps.CentreOfMass();
}
+
return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
}
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::radius(const std::shared_ptr<GeomAPI_Face>& theCylinder)
+{
+ double aRadius = -1.0;
+ if (theCylinder->isCylindrical()) {
+ const TopoDS_Shape& aShape = theCylinder->impl<TopoDS_Shape>();
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+ Handle(Geom_CylindricalSurface) aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf);
+ if (!aCyl.IsNull())
+ aRadius = aCyl->Radius();
+ }
+ return aRadius;
+}
+
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::minimalDistance(const GeomShapePtr& theShape1,
+ const GeomShapePtr& theShape2)
+{
+ const TopoDS_Shape& aShape1 = theShape1->impl<TopoDS_Shape>();
+ const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
+
+ BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
+ aDist.Perform();
+ return aDist.IsDone() ? aDist.Value() : Precision::Infinite();
+}
+
//==================================================================================================
std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::combineShapes(
const std::shared_ptr<GeomAPI_Shape> theCompound,
}
}
- // Map subshapes and shapes.
- BOPCol_IndexedDataMapOfShapeListOfShape aMapSA;
- BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapSA);
+ // Map sub-shapes and shapes.
+ TopTools_IndexedDataMapOfShapeListOfShape aMapSA;
+ TopExp::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapSA);
if(aMapSA.IsEmpty()) {
return aResult;
}
- // Get all shapes with common subshapes and free shapes.
+ // Get all shapes with common sub-shapes and free shapes.
NCollection_Map<TopoDS_Shape> aFreeShapes;
NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
- for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator
+ for(TopTools_IndexedDataMapOfShapeListOfShape::Iterator
anIter(aMapSA); anIter.More(); anIter.Next()) {
const TopoDS_Shape& aShape = anIter.Key();
- BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue();
+ TopTools_ListOfShape& aListOfShape = anIter.ChangeValue();
if(aListOfShape.IsEmpty()) {
continue;
}
} else {
NCollection_List<TopoDS_Shape> aTempList;
NCollection_Map<TopoDS_Shape> aTempMap;
- const TopoDS_Shape& aF = aListOfShape.First();
- const TopoDS_Shape& aL = aListOfShape.Last();
- aTempList.Append(aF);
- aTempList.Append(aL);
- aTempMap.Add(aF);
- aTempMap.Add(aL);
- aFreeShapes.Remove(aF);
- aFreeShapes.Remove(aL);
+ for (TopTools_ListOfShape::Iterator aListIt(aListOfShape); aListIt.More(); aListIt.Next()) {
+ aTempList.Append(aListIt.Value());
+ aTempMap.Add(aListIt.Value());
+ aFreeShapes.Remove(aListIt.Value());
+ }
aListOfShape.Clear();
for(NCollection_List<TopoDS_Shape>::Iterator
aTempIter(aTempList); aTempIter.More(); aTempIter.Next()) {
const TopoDS_Shape& aTempShape = aTempIter.Value();
- for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator
+ for(TopTools_IndexedDataMapOfShapeListOfShape::Iterator
anIter(aMapSA); anIter.More(); anIter.Next()) {
- BOPCol_ListOfShape& aTempListOfShape = anIter.ChangeValue();
+ TopTools_ListOfShape& aTempListOfShape = anIter.ChangeValue();
if(aTempListOfShape.IsEmpty()) {
continue;
} else if(aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) {
aTempListOfShape.Clear();
} else if(aTempListOfShape.Size() > 1) {
- if(aTempListOfShape.First() == aTempShape) {
- const TopoDS_Shape& aTL = aTempListOfShape.Last();
- if(aTempMap.Add(aTL)) {
- aTempList.Append(aTL);
- aFreeShapes.Remove(aTL);
- }
- aTempListOfShape.Clear();
- } else if(aTempListOfShape.Last() == aTempShape) {
- const TopoDS_Shape& aTF = aTempListOfShape.First();
- if(aTempMap.Add(aTF)) {
- aTempList.Append(aTF);
- aFreeShapes.Remove(aTF);
+ TopTools_ListOfShape::Iterator anIt1(aTempListOfShape);
+ for (; anIt1.More(); anIt1.Next()) {
+ if (anIt1.Value() == aTempShape) {
+ TopTools_ListOfShape::Iterator anIt2(aTempListOfShape);
+ for (; anIt2.More(); anIt2.Next())
+ {
+ if (anIt2.Value() != anIt1.Value()) {
+ if (aTempMap.Add(anIt2.Value())) {
+ aTempList.Append(anIt2.Value());
+ aFreeShapes.Remove(anIt2.Value());
+ }
+ }
+ }
+ aTempListOfShape.Clear();
+ break;
}
- aTempListOfShape.Clear();
}
}
}
}
}
- // Combine shapes with common subshapes.
+ // Combine shapes with common sub-shapes.
for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator
anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
TopoDS_Shell aShell;
{
GeomShapePtr aResult = theCompound;
- if(!theCompound.get()) {
+ if (!theCompound.get()) {
return aResult;
}
addSimpleShapeToList(anInShape, anUngroupedShapes);
// Iterate over all shapes and find shapes with shared vertices.
- TopTools_ListOfShape aMapOrder;
- BOPCol_DataMapOfShapeListOfShape aVertexShapesMap;
- for(NCollection_List<TopoDS_Shape>::Iterator aShapesIt(anUngroupedShapes);
- aShapesIt.More();
- aShapesIt.Next()) {
+ TopTools_ListOfShape allVertices;
+ TopTools_DataMapOfShapeListOfShape aVertexShapesMap;
+ for (NCollection_List<TopoDS_Shape>::Iterator aShapesIt(anUngroupedShapes);
+ aShapesIt.More();
+ aShapesIt.Next()) {
const TopoDS_Shape& aShape = aShapesIt.Value();
- for(TopExp_Explorer aShapeExp(aShape, TopAbs_VERTEX);
- aShapeExp.More();
- aShapeExp.Next()) {
+ for (TopExp_Explorer aShapeExp(aShape, TopAbs_VERTEX);
+ aShapeExp.More();
+ aShapeExp.Next()) {
const TopoDS_Shape& aVertex = aShapeExp.Current();
if (!aVertexShapesMap.IsBound(aVertex)) {
NCollection_List<TopoDS_Shape> aList;
aList.Append(aShape);
- aMapOrder.Append(aVertex);
+ allVertices.Append(aVertex);
aVertexShapesMap.Bind(aVertex, aList);
- } else {
- if(!aVertexShapesMap.ChangeFind(aVertex).Contains(aShape)) {
+ }
+ else {
+ if (!aVertexShapesMap.ChangeFind(aVertex).Contains(aShape)) {
aVertexShapesMap.ChangeFind(aVertex).Append(aShape);
}
}
}
// Iterate over the map and group shapes.
- NCollection_Vector<TopTools_ListOfShape> aGroups;
- while (!aMapOrder.IsEmpty()) {
+ NCollection_Vector<TopTools_MapOfShape> aGroups; // groups of shapes connected by vertices
+ while (!allVertices.IsEmpty()) {
// Get first group of shapes in map, and then unbind it.
- const TopoDS_Shape& aKey = aMapOrder.First();
- TopTools_ListOfShape aGroupedShapes = aVertexShapesMap.Find(aKey);
+ const TopoDS_Shape& aKey = allVertices.First();
+ TopTools_ListOfShape aConnectedShapes = aVertexShapesMap.Find(aKey);
aVertexShapesMap.UnBind(aKey);
- aMapOrder.Remove(aKey);
+ allVertices.Remove(aKey);
// Iterate over shapes in this group and add to it shapes from groups in map.
- for(TopTools_ListOfShape::Iterator aGroupIt(aGroupedShapes);
- aGroupIt.More(); aGroupIt.Next()) {
- const TopoDS_Shape& aGroupedShape = aGroupIt.Value();
+ for (TopTools_ListOfShape::Iterator aConnectedIt(aConnectedShapes);
+ aConnectedIt.More(); aConnectedIt.Next()) {
+ const TopoDS_Shape& aConnected = aConnectedIt.Value();
TopTools_ListOfShape aKeysToUnbind;
- for(TopTools_ListOfShape::Iterator aKeysIt(aMapOrder);
- aKeysIt.More();
- aKeysIt.Next()) {
- const TopTools_ListOfShape& aGroupInMap = aVertexShapesMap(aKeysIt.Value());
- if(!aGroupInMap.Contains(aGroupedShape)) {
- // Group in map does not containt shape from our group, so go to the next group in map.
+ for (TopTools_ListOfShape::Iterator aKeysIt(allVertices);
+ aKeysIt.More();
+ aKeysIt.Next()) {
+ const TopTools_ListOfShape& anOtherConnected = aVertexShapesMap(aKeysIt.Value());
+ if (!anOtherConnected.Contains(aConnected)) {
+ // Other connected group does not contain shape from our connected group
continue;
}
- // Iterate over shape in group in map, and add new shapes into our group.
- for(TopTools_ListOfShape::Iterator aGroupInMapIt(aGroupInMap);
- aGroupInMapIt.More();
- aGroupInMapIt.Next()) {
- const TopoDS_Shape& aShape = aGroupInMapIt.Value();
- if (!aGroupedShapes.Contains(aShape)) {
- aGroupedShapes.Append(aShape);
+ // Other is connected to our, so add them to our connected
+ for (TopTools_ListOfShape::Iterator anOtherIt(anOtherConnected);
+ anOtherIt.More();
+ anOtherIt.Next()) {
+ const TopoDS_Shape& aShape = anOtherIt.Value();
+ if (!aConnectedShapes.Contains(aShape)) {
+ aConnectedShapes.Append(aShape);
}
}
// Save key to unbind from this map.
aKeysToUnbind.Append(aKeysIt.Value());
}
// Unbind groups from map that we added to our group.
- for(TopTools_ListOfShape::Iterator aKeysIt(aKeysToUnbind);
- aKeysIt.More();
- aKeysIt.Next()) {
+ for (TopTools_ListOfShape::Iterator aKeysIt(aKeysToUnbind);
+ aKeysIt.More();
+ aKeysIt.Next()) {
aVertexShapesMap.UnBind(aKeysIt.Value());
- aMapOrder.Remove(aKeysIt.Value());
+ allVertices.Remove(aKeysIt.Value());
}
}
- // Sort shapes.
- TopTools_ListOfShape aSortedGroup;
- for(int aST = TopAbs_COMPOUND; aST <= TopAbs_SHAPE; ++aST) {
- TopTools_ListOfShape::Iterator anIt(aGroupedShapes);
+ // Sort shapes from the most complicated to the simplest ones
+ TopTools_MapOfShape aSortedGroup;
+ for (int aST = TopAbs_COMPOUND; aST <= TopAbs_SHAPE; ++aST) {
+ TopTools_ListOfShape::Iterator anIt(aConnectedShapes);
while (anIt.More()) {
- if(anIt.Value().ShapeType() == aST) {
- aSortedGroup.Append(anIt.Value());
- aGroupedShapes.Remove(anIt);
- } else {
+ if (anIt.Value().ShapeType() == aST) {
+ aSortedGroup.Add(anIt.Value());
+ aConnectedShapes.Remove(anIt);
+ }
+ else {
anIt.Next();
}
}
BRep_Builder aBuilder;
aBuilder.MakeCompound(aCompound);
ListOfShape aCompSolids, aFreeSolids;
- for(NCollection_Vector<NCollection_List<TopoDS_Shape>>::Iterator
- anIt(aGroups); anIt.More(); anIt.Next()) {
- NCollection_List<TopoDS_Shape> aGroup = anIt.Value();
+ for (NCollection_Vector<TopTools_MapOfShape>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) {
+ const TopTools_MapOfShape& aGroup = anIt.ChangeValue();
GeomShapePtr aGeomShape(new GeomAPI_Shape());
if(aGroup.Size() == 1) {
- aGeomShape->setImpl(new TopoDS_Shape(aGroup.First()));
+ TopTools_MapOfShape::Iterator aOneShapeIter(aGroup);
+ aGeomShape->setImpl(new TopoDS_Shape(aOneShapeIter.Value()));
} else {
- aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup)));
+ // make sub-shapes in the group have order same as in original shape
+ TopTools_ListOfShape anOrderedGoup;
+ NCollection_List<TopoDS_Shape>::Iterator anUngrouped(anUngroupedShapes);
+ for (; anUngrouped.More(); anUngrouped.Next()) {
+ if (aGroup.Contains(anUngrouped.Value()))
+ anOrderedGoup.Append(anUngrouped.Value());
+ }
+ aGeomShape->setImpl(new TopoDS_Shape(makeCompound(anOrderedGoup)));
aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
GeomAPI_Shape::COMPSOLID,
aCompSolids,
return aResultPoints;
}
-//==================================================================================================
-std::shared_ptr<GeomAPI_Shape>
- GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace)
-{
- if (!theFace.get())
- return std::shared_ptr<GeomAPI_Shape>();
-
- TopoDS_Face aPlaneFace = TopoDS::Face(theFace->impl<TopoDS_Shape>());
- if (aPlaneFace.IsNull())
- return std::shared_ptr<GeomAPI_Shape>();
-
- Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aPlaneFace));
- if (aPlane.IsNull())
- return std::shared_ptr<GeomAPI_Shape>();
-
- // make an infinity face on the plane
- TopoDS_Shape anInfiniteFace = BRepBuilderAPI_MakeFace(aPlane->Pln()).Shape();
-
- std::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape);
- aResult->setImpl(new TopoDS_Shape(anInfiniteFace));
- return aResult;
-}
-
//==================================================================================================
std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_ShapeTools::fitPlaneToBox(
const std::shared_ptr<GeomAPI_Shape> thePlane,
std::shared_ptr<GeomAPI_Vertex>& theV1,
std::shared_ptr<GeomAPI_Vertex>& theV2)
{
- if(!theShape.get()) {
- std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex);
+ static GeomVertexPtr aVertex;
+ if (!aVertex) {
+ aVertex = GeomVertexPtr(new GeomAPI_Vertex);
aVertex->setImpl(new TopoDS_Vertex());
- theV1 = aVertex;
- theV2 = aVertex;
- return;
}
- const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
- TopoDS_Vertex aV1, aV2;
- ShapeAnalysis::FindBounds(aShape, aV1, aV2);
-
- std::shared_ptr<GeomAPI_Vertex> aGeomV1(new GeomAPI_Vertex()), aGeomV2(new GeomAPI_Vertex());
- aGeomV1->setImpl(new TopoDS_Vertex(aV1));
- aGeomV2->setImpl(new TopoDS_Vertex(aV2));
- theV1 = aGeomV1;
- theV2 = aGeomV2;
+ theV1 = aVertex;
+ theV2 = aVertex;
+
+ if (theShape) {
+ const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+ TopoDS_Vertex aV1, aV2;
+ ShapeAnalysis::FindBounds(aShape, aV1, aV2);
+
+ std::shared_ptr<GeomAPI_Vertex> aGeomV1(new GeomAPI_Vertex()), aGeomV2(new GeomAPI_Vertex());
+ aGeomV1->setImpl(new TopoDS_Vertex(aV1));
+ aGeomV2->setImpl(new TopoDS_Vertex(aV2));
+ theV1 = aGeomV1;
+ theV2 = aGeomV2;
+ }
}
//==================================================================================================
}
aBOP.Perform();
-#ifdef USE_OCCT_720
if (aBOP.HasErrors())
return;
-#else
- if (aBOP.ErrorStatus())
- return;
-#endif
// Collect splits
const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
}
aBOP.Perform();
-#ifdef USE_OCCT_720
if (aBOP.HasErrors())
return;
-#else
- if (aBOP.ErrorStatus())
- return;
-#endif
// Collect splits
const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
}
//==================================================================================================
+#ifdef FEATURE_MULTIROTATION_TWO_DIRECTIONS
std::shared_ptr<GeomAPI_Dir> GeomAlgoAPI_ShapeTools::buildDirFromAxisAndShape(
const std::shared_ptr<GeomAPI_Shape> theBaseShape,
const std::shared_ptr<GeomAPI_Ax1> theAxis)
aCentreOfMassPoint.Z()-aPoint.Z()));
return aDir;
}
+#endif
//==================================================================================================
static TopoDS_Wire fixParametricGaps(const TopoDS_Wire& theWire)
}
return anEdge;
}
+
+ListOfShape GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(const GeomShapePtr& theShape)
+{
+ ListOfShape aSubShapes;
+
+ if (!theShape->isCompound() && !theShape->isCompSolid() &&
+ !theShape->isShell() && !theShape->isWire()) {
+ return aSubShapes;
+ }
+
+ for (GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
+ GeomShapePtr aSubShape = anIt.current();
+ if (aSubShape->isVertex() || aSubShape->isEdge() ||
+ aSubShape->isFace() || aSubShape->isSolid()) {
+ aSubShapes.push_back(aSubShape);
+ } else {
+ aSubShapes.splice(aSubShapes.end(), getLowLevelSubShapes(aSubShape));
+ }
+ }
+
+ return aSubShapes;
+}
\ No newline at end of file