+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
// File: GeomAlgoAPI_SketchBuilder.cpp
// Created: 02 Jun 2014
// Author: Artem ZHIDKOV
#include <GeomAlgoAPI_SketchBuilder.h>
+#include <GeomAPI_PlanarEdges.h>
#include <set>
void GeomAlgoAPI_SketchBuilder::createFaces(
- const boost::shared_ptr<GeomAPI_Pnt>& theOrigin, const boost::shared_ptr<GeomAPI_Dir>& theDirX,
- const boost::shared_ptr<GeomAPI_Dir>& theDirY, const boost::shared_ptr<GeomAPI_Dir>& theNorm,
- const std::list<boost::shared_ptr<GeomAPI_Shape> >& theFeatures,
- std::list<boost::shared_ptr<GeomAPI_Shape> >& theResultFaces,
- std::list<boost::shared_ptr<GeomAPI_Shape> >& theResultWires)
+ const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
+ std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces,
+ std::list<std::shared_ptr<GeomAPI_Shape> >& theResultWires)
{
if (theFeatures.empty())
return;
TopoDS_Shape aFeaturesCompound;
// Obtain only edges from the features list
- std::list<boost::shared_ptr<GeomAPI_Shape> > anEdges;
- std::list<boost::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theFeatures.begin();
+ std::list<std::shared_ptr<GeomAPI_Shape> > anEdges;
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theFeatures.begin();
for (; aFeatIt != theFeatures.end(); aFeatIt++) {
- boost::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
+ std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
if (anEdge.ShapeType() == TopAbs_EDGE)
anEdges.push_back(aShape);
if (anEdges.size() == 1) { // If there is only one feature, BOPAlgo_Builder will decline to work. Need to process it anyway
aFeaturesCompound = anEdges.front()->impl<TopoDS_Shape>();
} else {
- std::list<boost::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = anEdges.begin();
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = anEdges.begin();
for (; anIt != anEdges.end(); anIt++) {
- boost::shared_ptr<GeomAPI_Shape> aPreview(*anIt);
+ std::shared_ptr<GeomAPI_Shape> aPreview(*anIt);
aBuilder.AddArgument(aPreview->impl<TopoDS_Edge>());
}
aPF.SetArguments(aBuilder.Arguments());
return;
gp_Dir aDirX = theDirX->impl<gp_Dir>();
- gp_Dir aDirY = theDirY->impl<gp_Dir>();
gp_Dir aNorm = theNorm->impl<gp_Dir>();
+ gp_Dir aDirY = aNorm.Crossed(aDirX);
gp_Pln aPlane(theOrigin->impl<gp_Pnt>(), aNorm);
while (aMapVE.Extent() > 0) {
if (aCurVertex.IsNull())
return;
+ if (!aProcEdges.empty())
+ aBindingEdge = aProcEdges.back();
findNextVertex(aCurVertex, aMapVE, aCurDir, aCurNorm, aNextVertex, aBindingEdge, aNextDir);
aCurNorm = aNorm;
aProcEdges.pop_back();
} while (aCurVertex != aProcVertexes.back());
aCurDir = aCN.Reversed();
- //aCurNorm = aNorm.Reversed();
+ aCurNorm = aNorm.Reversed();
continue;
}
}
TopoDS_Face aPatch;
createFace(*aVertIter, anEdgeIter, aProcEdges.end(), aPlane, aPatch);
if (!aPatch.IsNull()) {
- boost::shared_ptr<GeomAPI_Shape> aFace(new GeomAPI_Shape);
+ std::shared_ptr<GeomAPI_Shape> aFace(new GeomAPI_Shape);
aFace->setImpl(new TopoDS_Face(aPatch));
theResultFaces.push_back(aFace);
}
std::list<TopoDS_Edge>::iterator aCopyELoop = anEdgeIter;
removeWasteEdges(aVertIter, anEdgeIter, aProcVertexes.end(), aProcEdges.end(), aMapVE);
- // Recalculate current vertex and current direction
- aProcEdges.clear();
- aProcVertexes.clear();
- if (aMapVE.Extent() > 0)
- {
- aNextVertex = findStartVertex(aMapVE, aDirX, aDirY);
- aProcVertexes.push_back(aNextVertex);
+ // revert the list of remaining edges
+ std::list<TopoDS_Vertex> aRemainVertexes;
+ for (; aVertIter != aProcVertexes.end(); aVertIter++)
+ aRemainVertexes.push_front(*aVertIter);
+ std::list<TopoDS_Edge> aRemainEdges;
+ for (; anEdgeIter != aProcEdges.end(); anEdgeIter++)
+ aRemainEdges.push_front(*anEdgeIter);
+ // remove edges and vertexes used in the loop and add remaining ones
+ if (aCopyVLoop != aProcVertexes.begin()) {
+ aVertIter = aCopyVLoop;
+ aVertIter--;
+ } else
+ aVertIter = aProcVertexes.end();
+ aProcVertexes.erase(aCopyVLoop, aProcVertexes.end());
+ aProcVertexes.insert(aProcVertexes.end(), aRemainVertexes.begin(), aRemainVertexes.end());
+ if (aCopyELoop != aProcEdges.begin()) {
+ anEdgeIter = aCopyELoop;
+ anEdgeIter--;
+ } else
+ anEdgeIter = aProcEdges.end();
+ aProcEdges.erase(aCopyELoop, aProcEdges.end());
+ aProcEdges.insert(aProcEdges.end(), aRemainEdges.begin(), aRemainEdges.end());
+
+ if (aVertIter == aProcVertexes.end())
+ aVertIter = aProcVertexes.begin();
+ else
+ aVertIter++;
+ if (anEdgeIter == aProcEdges.end())
+ anEdgeIter = aProcEdges.begin();
+ else
+ anEdgeIter++;
+ aCopyVLoop = aVertIter;
+ aCopyELoop = anEdgeIter;
+
+ if (aVertIter != aProcVertexes.end() &&
+ aMapVE.Contains(*aVertIter) && aMapVE.FindFromKey(*aVertIter).Extent() <= 1)
+ removeWasteEdges(aVertIter, anEdgeIter, aProcVertexes.end(), aProcEdges.end(), aMapVE);
+ if (aCopyVLoop != aVertIter)
+ aProcVertexes.erase(aCopyVLoop, aVertIter);
+ if (aCopyELoop != anEdgeIter)
+ aProcEdges.erase(aCopyELoop, anEdgeIter);
+
+ // Check whether the next vertex already exists
+ if (aVertIter != aProcVertexes.end())
+ aVertIter++;
+ if (aVertIter != aProcVertexes.end() && anEdgeIter != aProcEdges.end()) {
+ aNextVertex = *aVertIter;
+ aNextDir = getOuterEdgeDirection(*anEdgeIter, aNextVertex);
+ aProcVertexes.erase(++aVertIter, aProcVertexes.end());
+ aProcEdges.erase(++anEdgeIter, aProcEdges.end());
+ } else {
+ // Recalculate current vertex and current direction
+ aProcEdges.clear();
+ aProcVertexes.clear();
+ if (aMapVE.Extent() > 0) {
+ aNextVertex = findStartVertex(aMapVE, aDirX, aDirY);
+ aProcVertexes.push_back(aNextVertex);
+ }
+ aNextDir = aDirY.Reversed();
+ aCurNorm = aNorm.Reversed();
}
- aNextDir = aDirY.Reversed();
- aCurNorm = aNorm.Reversed();
}
// if next vertex connected only to alone edge, this is a part of wire (not a closed loop),
std::list<TopoDS_Wire>::const_iterator aTailIter = aTail.begin();
for (; aTailIter != aTail.end(); aTailIter++)
if (!aTailIter->IsNull()) {
- boost::shared_ptr<GeomAPI_Shape> aWire(new GeomAPI_Shape);
+ std::shared_ptr<GeomAPI_Shape> aWire(new GeomAPI_Shape);
aWire->setImpl(new TopoDS_Shape(*aTailIter));
theResultWires.push_back(aWire);
}
fixIntersections(theResultFaces);
}
+void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::shared_ptr<GeomAPI_Shape>& theWire,
+ std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
+{
+ std::list<std::shared_ptr<GeomAPI_Shape> > aFilteredWires;
+ std::shared_ptr<GeomAPI_PlanarEdges> aWire =
+ std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(theWire);
+ if(aWire) {
+ // Filter wires, return only faces.
+ createFaces(theOrigin, theDirX, theNorm,
+ aWire->getEdges(), theResultFaces, aFilteredWires);
+
+ return;
+ } else { // it may be only one circle
+ std::shared_ptr<GeomAPI_Edge> anEdge = std::dynamic_pointer_cast<GeomAPI_Edge>(theWire);
+ if (anEdge) {
+ std::list<std::shared_ptr<GeomAPI_Shape> > aList;
+ aList.push_back(anEdge);
+ createFaces(theOrigin, theDirX, theNorm,
+ aList, theResultFaces, aFilteredWires);
+ }
+ }
+}
+
+
void GeomAlgoAPI_SketchBuilder::fixIntersections(
- std::list<boost::shared_ptr<GeomAPI_Shape> >& theFaces)
+ std::list<std::shared_ptr<GeomAPI_Shape> >& theFaces)
{
BRepClass_FaceClassifier aClassifier;
- std::list<boost::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
- std::list<boost::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
+ std::list<std::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
+ std::list<std::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
for (; anIter1 != theFaces.end(); anIter1++) {
anIter2 = anIter1;
for (++anIter2; anIter2 != theFaces.end(); anIter2++) {
aCut.Build();
TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE);
bool isFirstFace = true;
- for (anExp.Next(); anExp.More(); anExp.Next()) {
+ for (; anExp.More(); anExp.Next()) {
if (anExp.Current().ShapeType() != TopAbs_FACE) continue;
if (isFirstFace) {
(*anIter2)->setImpl(new TopoDS_Shape(anExp.Current()));
isFirstFace = false;
} else {
- boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
aShape->setImpl(new TopoDS_Shape(anExp.Current()));
theFaces.push_back(aShape);
}
aCut.Build();
TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE);
bool isFirstFace = true;
- for (anExp.Next(); anExp.More(); anExp.Next()) {
+ for (; anExp.More(); anExp.Next()) {
if (anExp.Current().ShapeType() != TopAbs_FACE) continue;
if (isFirstFace) {
(*anIter1)->setImpl(new TopoDS_Shape(anExp.Current()));
isFirstFace = false;
} else {
- boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
aShape->setImpl(new TopoDS_Shape(anExp.Current()));
theFaces.push_back(aShape);
}
const gp_Dir& theStartDir, const gp_Dir& theNormal, TopoDS_Vertex& theNextVertex,
TopoDS_Edge& theNextEdge, gp_Dir& theNextDir)
{
+ theNextVertex = TopoDS_Vertex();
const BOPCol_ListOfShape& anEdgesList = theVertexEdgeMap.FindFromKey(theStartVertex);
+ int anEdgesNum = anEdgesList.Extent();
BOPCol_ListOfShape::Iterator aEdIter(anEdgesList);
double aBestEdgeProj = DBL_MAX;
for (; aEdIter.More(); aEdIter.Next()) {
// where (-1, 0] corresponds to the angles (pi/2, 0] between theStartDir and aTang
// and [0, 1) corresponds to the angles [0, -pi/2)
double aProj = (aTang.Dot(theStartDir) - 1.0) * 0.5;
- if (fabs(fabs(aProj) - 1) < tolerance)
+ if (anEdgesNum > 1 && fabs(fabs(aProj) - 1) < tolerance)
continue;
if (theStartDir.DotCross(aTang, theNormal) < tolerance)
aProj *= -1.0;
}
}
}
+
+ // Probably there are two tangent edges. We will take the edge differs from current one
+ if (theNextVertex.IsNull() && anEdgesNum == 2) {
+ BOPCol_ListOfShape::Iterator aEdIter(anEdgesList);
+ if (aEdIter.Value() == theNextEdge)
+ aEdIter.Next();
+ theNextEdge = static_cast<const TopoDS_Edge&>(aEdIter.Value());
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(theNextEdge, aV1, aV2);
+ theNextVertex = theStartVertex.IsSame(aV1) ? aV2 : aV1;
+ theNextDir = getOuterEdgeDirection(theNextEdge, theNextVertex);
+ }
}
static void addEdgeToWire(const TopoDS_Edge& theEdge, const BRep_Builder& theBuilder,