#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeReference.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_Prism.h>
#include <GeomAlgoAPI_ShapeTools.h>
// Searching faces with common edges.
ListOfShape aShells;
ListOfShape aFreeFaces;
- GeomAlgoAPI_ShapeTools::combineFacesToShells(aFacesList, aShells, aFreeFaces);
+ std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
+ GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
if(aShells.empty()) {
aShells = aFreeFaces;
} else {
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_ResultBody.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
#include <GeomAPI_Edge.h>
#include <GeomAPI_Lin.h>
// Searching faces with common edges.
ListOfShape aShells;
ListOfShape aFreeFaces;
- GeomAlgoAPI_ShapeTools::combineFacesToShells(aFacesList, aShells, aFreeFaces);
+ std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
+ GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
if(aShells.empty()) {
aShells = aFreeFaces;
} else {
if(aResult.ShapeType() == TopAbs_COMPOUND) {
aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
}
-
- myShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
- myShape->setImpl(new TopoDS_Shape(aResult));
+ if(aResult.ShapeType() == TopAbs_COMPOUND) {
+ std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
+ aCompound->setImpl(new TopoDS_Shape(aResult));
+ ListOfShape aCompSolids, aFreeSolids;
+ GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
+ if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
+ aResult = aCompSolids.front()->impl<TopoDS_Shape>();
+ } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
+ TopoDS_Compound aResultComp;
+ TopoDS_Builder aBuilder;
+ aBuilder.MakeCompound(aResultComp);
+ for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
+ aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+ }
+ for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
+ aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+ }
+ aResult = aResultComp;
+ }
+ }
// Fill data map to keep correct orientation of sub-shapes.
myMap = std::shared_ptr<GeomAPI_DataMapOfShapeShape>(new GeomAPI_DataMapOfShapeShape);
aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
myMap->bind(aCurrentShape, aCurrentShape);
}
-
+ myShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
+ myShape->setImpl(new TopoDS_Shape(aResult));
myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
myDone = true;
}
GeomLib_IsPlanarSurface isBasisPlanar(BRep_Tool::Surface(aBasisFace));
gp_Pln aBasisPln = isBasisPlanar.Plan();
Geom_Plane aBasisPlane(aBasisPln);
+ gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
+ if(aBasisPlane.Axis().Angle(anAxis) < Precision::Confusion()) {
+ return;
+ }
+ gp_Lin anAxisLin(anAxis);
// Creating circle for pipe.
gp_Pnt aBasisCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis)->impl<gp_Pnt>();
+ gp_Pnt aStartPnt = aBasisCentre;
const TopoDS_Shape& aBasisShape = theBasis->impl<TopoDS_Shape>();
- gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
- gp_Lin anAxisLin(anAxis);
Handle(Geom_Line) anAxisLine = new Geom_Line(anAxis);
- GeomAPI_ProjectPointOnCurve aProjection(aBasisCentre, anAxisLine);
+ if(anAxisLin.Contains(aStartPnt, Precision::Confusion())) {
+ aStartPnt.Translate(anAxis.Direction() ^ aBasisPln.Axis().Direction());
+ }
+ GeomAPI_ProjectPointOnCurve aProjection(aStartPnt, anAxisLine);
if(aProjection.NbPoints() != 1) {
return;
}
// Rotating base face with the negative value of "from angle".
gp_Trsf aBaseTrsf;
aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
- gp_Pnt aFromPnt = aBasisCentre.Transformed(aBaseTrsf);
+ gp_Pnt aFromPnt = aStartPnt.Transformed(aBaseTrsf);
aCircle = gp_Circ(gp_Ax2(aProjection.NearestPoint(), anAxis.Direction(), gp_Vec(aProjection.NearestPoint(), aFromPnt)),
aRadius);
BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBasisShape,
if(!anExp.More()) {
return;
}
+ if(aResult.ShapeType() == TopAbs_COMPOUND) {
+ aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
+ }
+ if(aResult.ShapeType() == TopAbs_COMPOUND) {
+ std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
+ aCompound->setImpl(new TopoDS_Shape(aResult));
+ ListOfShape aCompSolids, aFreeSolids;
+ GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
+ if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
+ aResult = aCompSolids.front()->impl<TopoDS_Shape>();
+ } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
+ TopoDS_Compound aResultComp;
+ TopoDS_Builder aBuilder;
+ aBuilder.MakeCompound(aResultComp);
+ for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
+ aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+ }
+ for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
+ aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+ }
+ aResult = aResultComp;
+ }
+ }
// fill data map to keep correct orientation of sub-shapes
myMap = std::shared_ptr<GeomAPI_DataMapOfShapeShape>(new GeomAPI_DataMapOfShapeShape());
myShape->setImpl(new TopoDS_Shape(aResult));
myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
myDone = true;
- return;
}
//=================================================================================================
}
//=================================================================================================
-void GeomAlgoAPI_ShapeTools::combineFacesToShells(const ListOfShape& theFacesList,
- ListOfShape& theShells,
- ListOfShape& theFreeFaces)
+void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+ const GeomAPI_Shape::ShapeType theType,
+ ListOfShape& theCombinedShapes,
+ ListOfShape& theFreeShapes)
{
- if(theFacesList.empty()) {
+ if(!theCompound.get()) {
return;
}
- // Adding all faces to compoud.
- std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(theFacesList);
- if(!aFacesCompound.get()) {
+ if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
return;
}
- // Map edges and faces.
- const TopoDS_Shape& aFacesComp = aFacesCompound->impl<TopoDS_Shape>();
+ TopAbs_ShapeEnum aTS = TopAbs_EDGE;
+ TopAbs_ShapeEnum aTA = TopAbs_FACE;
+ if(theType == GeomAPI_Shape::COMPSOLID) {
+ aTS = TopAbs_FACE;
+ aTA = TopAbs_SOLID;
+ }
+
+ // Map subshapes and shapes.
+ const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
BOPCol_IndexedDataMapOfShapeListOfShape aMapEF;
- BOPTools::MapShapesAndAncestors(aFacesComp, TopAbs_EDGE, TopAbs_FACE, aMapEF);
+ BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapEF);
if(aMapEF.IsEmpty()) {
return;
}
- // Get all faces with common edges and free faces.
- NCollection_Map<TopoDS_Shape> aFreeFaces;
- NCollection_Vector<NCollection_Map<TopoDS_Shape>> aFacesWithCommonEdges;
+ // Get all shapes with common subshapes and free shapes.
+ NCollection_Map<TopoDS_Shape> aFreeShapes;
+ NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
const TopoDS_Shape& aShape = anIter.Key();
BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue();
continue;
}
else if(aListOfShape.Size() == 1) {
- aFreeFaces.Add(aListOfShape.First());
+ aFreeShapes.Add(aListOfShape.First());
aListOfShape.Clear();
} else {
NCollection_Map<TopoDS_Shape> aTempMap;
aTempMap.Add(aListOfShape.First());
aTempMap.Add(aListOfShape.Last());
- aFreeFaces.Remove(aListOfShape.First());
- aFreeFaces.Remove(aListOfShape.Last());
+ aFreeShapes.Remove(aListOfShape.First());
+ aFreeShapes.Remove(aListOfShape.Last());
aListOfShape.Clear();
for(NCollection_Map<TopoDS_Shape>::Iterator aTempIter(aTempMap); aTempIter.More(); aTempIter.Next()) {
const TopoDS_Shape& aTempShape = aTempIter.Value();
} else if(aTempListOfShape.Size() > 1) {
if(aTempListOfShape.First() == aTempShape) {
aTempMap.Add(aTempListOfShape.Last());
- aFreeFaces.Remove(aTempListOfShape.Last());
+ aFreeShapes.Remove(aTempListOfShape.Last());
aTempListOfShape.Clear();
} else if(aTempListOfShape.Last() == aTempShape) {
aTempMap.Add(aTempListOfShape.First());
- aFreeFaces.Remove(aTempListOfShape.First());
+ aFreeShapes.Remove(aTempListOfShape.First());
aTempListOfShape.Clear();
}
}
}
}
- aFacesWithCommonEdges.Append(aTempMap);
+ aShapesWithCommonSubshapes.Append(aTempMap);
}
}
- // Make shells from faces with common edges.
- NCollection_Vector<TopoDS_Shape> aShells;
- for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aFacesWithCommonEdges); anIter.More(); anIter.Next()) {
+ // Combine shapes with common subshapes.
+ for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
TopoDS_Shell aShell;
+ TopoDS_CompSolid aCSolid;
TopoDS_Builder aBuilder;
- aBuilder.MakeShell(aShell);
+ theType == GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell);
const NCollection_Map<TopoDS_Shape>& aShapesMap = anIter.Value();
for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aShapesMap); aShIter.More(); aShIter.Next()) {
- const TopoDS_Shape& aFace = aShIter.Value();
- aBuilder.Add(aShell, aFace);
+ const TopoDS_Shape& aShape = aShIter.Value();
+ theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape);
}
- std::shared_ptr<GeomAPI_Shape> aGeomShell(new GeomAPI_Shape);
- aGeomShell->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShell));
- theShells.push_back(aGeomShell);
+ std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+ TopoDS_Shape* aSh = theType == GeomAPI_Shape::COMPSOLID ? new TopoDS_Shape(aCSolid) : new TopoDS_Shape(aShell);
+ aGeomShape->setImpl<TopoDS_Shape>(aSh);
+ theCombinedShapes.push_back(aGeomShape);
}
- // Adding free faces.
- for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aFreeFaces); aShIter.More(); aShIter.Next()) {
- const TopoDS_Shape& aFace = aShIter.Value();
- std::shared_ptr<GeomAPI_Shape> aGeomFace(new GeomAPI_Shape);
- aGeomFace->setImpl<TopoDS_Shape>(new TopoDS_Shape(aFace));
- theFreeFaces.push_back(aGeomFace);
+ // Adding free shapes.
+ for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aFreeShapes); aShIter.More(); aShIter.Next()) {
+ const TopoDS_Shape& aShape = aShIter.Value();
+ std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+ aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
+ theFreeShapes.push_back(aGeomShape);
}
}
/// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
static std::shared_ptr<GeomAPI_Pnt> centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape);
- /** \brief Combines faces with common edges to shells
- * \param[in] theFacesList list of faces to be combined.
+ /** \brief Combines faces with common edges to shells, or solids to compsolids.
+ * \param[in] theCompound compound of shapes.
+ * \param[in] theType type of combine.
* \param[out] theShells resulting shells.
* \param[out] theFreeFaces faces that does not have common edges.
*/
- static void combineFacesToShells(const ListOfShape& theFacesList,
- ListOfShape& theShells,
- ListOfShape& theFreeFaces);
+ static void combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+ const GeomAPI_Shape::ShapeType theType,
+ ListOfShape& theCombinedShapes,
+ ListOfShape& theFreeShapes);
};
#endif