X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_SketchBuilder.cpp;h=4e894827d7f63d037da9748132f9784a6107f721;hb=32e205a228d74cdc2627143cb32360e9a557d7dc;hp=ed3bf8fec901edecef4e221c3a9f8b6c55a4a515;hpb=d77708ba98445935aae7a0d93b5506e1f16018de;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index ed3bf8fec..4e894827d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -3,6 +3,7 @@ // Author: Artem ZHIDKOV #include +#include #include @@ -79,11 +80,11 @@ static void removeWasteEdges(std::list::iterator& theStartVertex, void GeomAlgoAPI_SketchBuilder::createFaces( - const boost::shared_ptr& theOrigin, const boost::shared_ptr& theDirX, - const boost::shared_ptr& theDirY, const boost::shared_ptr& theNorm, - const std::list >& theFeatures, - std::list >& theResultFaces, - std::list >& theResultWires) + const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, + const std::shared_ptr& theDirY, const std::shared_ptr& theNorm, + const std::list >& theFeatures, + std::list >& theResultFaces, + std::list >& theResultWires) { if (theFeatures.empty()) return; @@ -94,10 +95,10 @@ void GeomAlgoAPI_SketchBuilder::createFaces( TopoDS_Shape aFeaturesCompound; // Obtain only edges from the features list - std::list > anEdges; - std::list >::const_iterator aFeatIt = theFeatures.begin(); + std::list > anEdges; + std::list >::const_iterator aFeatIt = theFeatures.begin(); for (; aFeatIt != theFeatures.end(); aFeatIt++) { - boost::shared_ptr aShape(*aFeatIt); + std::shared_ptr aShape(*aFeatIt); const TopoDS_Edge& anEdge = aShape->impl(); if (anEdge.ShapeType() == TopAbs_EDGE) anEdges.push_back(aShape); @@ -106,9 +107,9 @@ void GeomAlgoAPI_SketchBuilder::createFaces( 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(); } else { - std::list >::const_iterator anIt = anEdges.begin(); + std::list >::const_iterator anIt = anEdges.begin(); for (; anIt != anEdges.end(); anIt++) { - boost::shared_ptr aPreview(*anIt); + std::shared_ptr aPreview(*anIt); aBuilder.AddArgument(aPreview->impl()); } aPF.SetArguments(aBuilder.Arguments()); @@ -155,6 +156,8 @@ void GeomAlgoAPI_SketchBuilder::createFaces( while (aMapVE.Extent() > 0) { if (aCurVertex.IsNull()) return; + if (!aProcEdges.empty()) + aBindingEdge = aProcEdges.back(); findNextVertex(aCurVertex, aMapVE, aCurDir, aCurNorm, aNextVertex, aBindingEdge, aNextDir); aCurNorm = aNorm; @@ -216,7 +219,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces( TopoDS_Face aPatch; createFace(*aVertIter, anEdgeIter, aProcEdges.end(), aPlane, aPatch); if (!aPatch.IsNull()) { - boost::shared_ptr aFace(new GeomAPI_Shape); + std::shared_ptr aFace(new GeomAPI_Shape); aFace->setImpl(new TopoDS_Face(aPatch)); theResultFaces.push_back(aFace); } @@ -237,18 +240,58 @@ void GeomAlgoAPI_SketchBuilder::createFaces( 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()); - // Recalculate current vertex and current direction - if (!aProcVertexes.empty()) { - aNextVertex = aProcVertexes.back(); - if (!aProcEdges.empty()) - aNextDir = getOuterEdgeDirection(aProcEdges.back(), aNextVertex); - else - aNextDir = aDirY; + 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(); } } @@ -280,7 +323,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces( std::list::const_iterator aTailIter = aTail.begin(); for (; aTailIter != aTail.end(); aTailIter++) if (!aTailIter->IsNull()) { - boost::shared_ptr aWire(new GeomAPI_Shape); + std::shared_ptr aWire(new GeomAPI_Shape); aWire->setImpl(new TopoDS_Shape(*aTailIter)); theResultWires.push_back(aWire); } @@ -328,13 +371,30 @@ void GeomAlgoAPI_SketchBuilder::createFaces( fixIntersections(theResultFaces); } +void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theDirY, + const std::shared_ptr& theNorm, + const std::shared_ptr& theWire, + std::list >& theResultFaces) +{ + std::shared_ptr aWire = std::dynamic_pointer_cast(theWire); + if(!aWire) + return; + // Filter wires, return only faces. + std::list > aFilteredWires; + createFaces(theOrigin, theDirX, theDirY, theNorm, + aWire->getEdges(), theResultFaces, aFilteredWires); +} + + void GeomAlgoAPI_SketchBuilder::fixIntersections( - std::list >& theFaces) + std::list >& theFaces) { BRepClass_FaceClassifier aClassifier; - std::list >::iterator anIter1 = theFaces.begin(); - std::list >::iterator anIter2; + std::list >::iterator anIter1 = theFaces.begin(); + std::list >::iterator anIter2; for (; anIter1 != theFaces.end(); anIter1++) { anIter2 = anIter1; for (++anIter2; anIter2 != theFaces.end(); anIter2++) { @@ -344,7 +404,8 @@ void GeomAlgoAPI_SketchBuilder::fixIntersections( for (; aVert2.More(); aVert2.Next()) { const TopoDS_Vertex& aV = (const TopoDS_Vertex&)aVert2.Current(); aClassifier.Perform(aF1, BRep_Tool::Pnt(aV), tolerance); - if (aClassifier.State() != TopAbs_IN && aClassifier.State() != TopAbs_ON) + TopAbs_State aState = aClassifier.State(); + if (aState != TopAbs_IN && aState != TopAbs_ON) break; } if (aVert2.More()) { // second shape is not inside first, change the shapes order and repeat comparision @@ -354,29 +415,42 @@ void GeomAlgoAPI_SketchBuilder::fixIntersections( for (; aVert1.More(); aVert1.Next()) { const TopoDS_Vertex& aV = (const TopoDS_Vertex&)aVert2.Current(); aClassifier.Perform(aF2, BRep_Tool::Pnt(aV), tolerance); - if (aClassifier.State() != TopAbs_IN && aClassifier.State() != TopAbs_ON) + TopAbs_State aState = aClassifier.State(); + if (aState != TopAbs_IN && aState != TopAbs_ON) break; } if (!aVert1.More()) { // first shape should be cut from the second BRepAlgoAPI_Cut aCut((*anIter2)->impl(), (*anIter1)->impl()); aCut.Build(); TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE); - (*anIter2)->setImpl(new TopoDS_Shape(anExp.Current())); - for (anExp.Next(); anExp.More(); anExp.Next()) { - boost::shared_ptr aShape(new GeomAPI_Shape); - aShape->setImpl(new TopoDS_Shape(anExp.Current())); - theFaces.push_back(aShape); + bool isFirstFace = true; + for (; anExp.More(); anExp.Next()) { + if (anExp.Current().ShapeType() != TopAbs_FACE) continue; + if (isFirstFace) { + (*anIter2)->setImpl(new TopoDS_Shape(anExp.Current())); + isFirstFace = false; + } else { + std::shared_ptr aShape(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(anExp.Current())); + theFaces.push_back(aShape); + } } } } else { // second shape should be cut from the first BRepAlgoAPI_Cut aCut((*anIter1)->impl(), (*anIter2)->impl()); aCut.Build(); TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE); - (*anIter1)->setImpl(new TopoDS_Shape(anExp.Current())); - for (anExp.Next(); anExp.More(); anExp.Next()) { - boost::shared_ptr aShape(new GeomAPI_Shape); - aShape->setImpl(new TopoDS_Shape(anExp.Current())); - theFaces.push_back(aShape); + bool isFirstFace = true; + for (; anExp.More(); anExp.Next()) { + if (anExp.Current().ShapeType() != TopAbs_FACE) continue; + if (isFirstFace) { + (*anIter1)->setImpl(new TopoDS_Shape(anExp.Current())); + isFirstFace = false; + } else { + std::shared_ptr aShape(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(anExp.Current())); + theFaces.push_back(aShape); + } } } } @@ -412,7 +486,9 @@ void findNextVertex(const TopoDS_Vertex& theStartVertex, 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()) { @@ -424,7 +500,7 @@ void findNextVertex(const TopoDS_Vertex& theStartVertex, // 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; @@ -450,6 +526,18 @@ void findNextVertex(const TopoDS_Vertex& theStartVertex, } } } + + // 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(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,