1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: GEOMAlgo_FinderShapeOn2.cxx
24 // Created: Fri Mar 4 10:31:06 2005
25 // Author: Peter KURNEV
28 #include <GEOMAlgo_FinderShapeOn2.hxx>
32 #include <Precision.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_MapOfInteger.hxx>
36 #include <gp_Trsf.hxx>
37 #include <gp_Cylinder.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
42 #include <Poly_Array1OfTriangle.hxx>
43 #include <Poly_Triangle.hxx>
44 #include <Poly_PolygonOnTriangulation.hxx>
45 #include <Poly_Triangulation.hxx>
46 #include <Poly_Polygon3D.hxx>
48 #include <Geom_Curve.hxx>
49 #include <Geom_Surface.hxx>
50 #include <GeomAdaptor_Surface.hxx>
51 #include <GeomAbs_SurfaceType.hxx>
52 #include <GeomAdaptor_Curve.hxx>
53 #include <GeomAbs_CurveType.hxx>
55 #include <TopAbs_State.hxx>
57 #include <TopLoc_Location.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Vertex.hxx>
61 #include <TopoDS_Face.hxx>
62 #include <TopoDS_Edge.hxx>
65 #include <TopExp_Explorer.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRepLib_MakeEdge.hxx>
72 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
74 #include <GEOMAlgo_SurfaceTools.hxx>
75 #include <GEOMAlgo_StateCollector.hxx>
76 #include <GEOMAlgo_FinderShapeOn.hxx>
78 #include <GEOMAlgo_PassKey.hxx>
79 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
80 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
82 //=======================================================================
83 //function : GEOMAlgo_FinderShapeOn1
85 //=======================================================================
86 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
91 myShapeType=TopAbs_VERTEX;
92 myState=GEOMAlgo_ST_UNKNOWN;
96 //=======================================================================
99 //=======================================================================
100 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
103 //=======================================================================
106 //=======================================================================
107 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
111 //=======================================================================
114 //=======================================================================
115 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
119 //=======================================================================
120 //function : SetShapeType
122 //=======================================================================
123 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
127 //=======================================================================
128 //function : ShapeType
130 //=======================================================================
131 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
135 //=======================================================================
136 //function : SetState
138 //=======================================================================
139 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
143 //=======================================================================
146 //=======================================================================
147 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
151 //=======================================================================
152 //function : SetNbPntsMin
154 //=======================================================================
155 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
159 //=======================================================================
160 //function : NbPntsMin
162 //=======================================================================
163 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
167 //=======================================================================
168 //function : SetNbPntsMax
170 //=======================================================================
171 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
175 //=======================================================================
176 //function : NbPntsMax
178 //=======================================================================
179 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
183 //=======================================================================
186 //=======================================================================
187 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
191 //=======================================================================
194 //=======================================================================
195 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
197 Standard_Integer i, aNb;
198 TopTools_ListOfShape* pL;
200 pL=(TopTools_ListOfShape*) &myLS;
204 for (i=1; i<=aNb; ++i) {
205 const TopoDS_Shape& aS=myMSS.FindKey(i);
206 if (aS.ShapeType()==myShapeType) {
212 //=======================================================================
215 //=======================================================================
216 void GEOMAlgo_FinderShapeOn2::Perform()
228 // Initialize the context
229 GEOMAlgo_ShapeAlgo::Perform();
231 myClsf->SetTolerance(myTolerance);
238 if (myShapeType==TopAbs_VERTEX) {
247 if (myShapeType==TopAbs_EDGE) {
256 if (myShapeType==TopAbs_FACE) {
264 //=======================================================================
265 //function : CheckData
267 //=======================================================================
268 void GEOMAlgo_FinderShapeOn2::CheckData()
270 Standard_Integer iErr;
274 if(myClsf.IsNull()) {
275 myErrorStatus=10; // myClsf=NULL
280 iErr=myClsf->ErrorStatus();
282 myErrorStatus=41; // invalid data for classifier
286 if (myShape.IsNull()) {
287 myErrorStatus=11; // myShape=NULL
291 if (!(myShapeType==TopAbs_VERTEX ||
292 myShapeType==TopAbs_EDGE ||
293 myShapeType==TopAbs_FACE ||
294 myShapeType==TopAbs_SOLID)) {
295 myErrorStatus=12; // unallowed sub-shape type
299 if (myState==GEOMAlgo_ST_UNKNOWN ||
300 myState==GEOMAlgo_ST_INOUT) {
301 myErrorStatus=13; // unallowed state type
305 //=======================================================================
306 //function : ProcessVertices
308 //=======================================================================
309 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
313 Standard_Boolean bIsConformState;
314 Standard_Integer i, aNb, iErr;
316 TopTools_IndexedMapOfShape aM;
319 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
321 for (i=1; i<=aNb; ++i) {
322 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
323 aP=BRep_Tool::Pnt(aV);
327 iErr=myClsf->ErrorStatus();
329 myErrorStatus=40; // point can not be classified
334 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
336 if (myShapeType==TopAbs_VERTEX){
337 if (bIsConformState) {
341 else if (bIsConformState || aSt==TopAbs_ON) {
346 //=======================================================================
347 //function : ProcessEdges
349 //=======================================================================
350 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
354 Standard_Boolean bIsConformState, bIsToBreak;
355 Standard_Integer i, aNb, iCnt, iErr;
357 TopTools_IndexedMapOfShape aM;
358 TopExp_Explorer aExp;
359 GEOMAlgo_ListIteratorOfListOfPnt aIt;
361 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
363 for (i=1; i<=aNb; ++i) {
364 GEOMAlgo_ListOfPnt aLP;
365 GEOMAlgo_StateCollector aSC;
367 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
369 aExp.Init(aE, TopAbs_VERTEX);
370 for (; aExp.More(); aExp.Next()) {
371 const TopoDS_Shape& aV=aExp.Current();
373 bIsConformState=myMSS.Contains(aV);
374 if (!bIsConformState) {
375 break;// vertex has non-conformed state
378 aSt=myMSS.FindFromKey(aV);
379 aSC.AppendState(aSt);
383 if (!bIsConformState) {
384 continue; // vertex has non-conformed state,skip edge
387 if (BRep_Tool::Degenerated(aE)) {
392 if (myState==GEOMAlgo_ST_ON) {
393 Standard_Boolean bCanBeON;
394 Standard_Real aT1, aT2;
395 Handle(Geom_Curve) aC;
397 aC=BRep_Tool::Curve(aE, aT1, aT2);
398 bCanBeON=myClsf->CanBeON(aC);
404 InnerPoints(aE, aLP);
409 bIsConformState=Standard_True;
411 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
413 if (iCnt > myNbPntsMax) {
418 const gp_Pnt& aP=aIt.Value();
422 iErr=myClsf->ErrorStatus();
424 myErrorStatus=40; // point can not be classified
430 bIsToBreak=aSC.AppendState(aSt);
438 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
439 if (myShapeType==TopAbs_EDGE) {
440 if (bIsConformState) {
444 else if (bIsConformState || aSt==TopAbs_ON) {
447 } // for (i=1; i<=aNb; ++i) next edge
449 //=======================================================================
450 //function : ProcessFaces
452 //=======================================================================
453 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
457 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
458 Standard_Integer i, aNbF, iCnt, iErr;
460 TopTools_IndexedMapOfShape aM;
461 TopExp_Explorer aExp;
462 GEOMAlgo_ListIteratorOfListOfPnt aIt;
464 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
466 for (i=1; i<=aNbF; ++i) {
467 GEOMAlgo_StateCollector aSC;
468 GEOMAlgo_ListOfPnt aLP;
470 const TopoDS_Face& aF=TopoDS::Face(aM(i));
472 if (myState==GEOMAlgo_ST_ON) {
473 Handle(Geom_Surface) aS;
475 aS=BRep_Tool::Surface(aF);
476 bCanBeON=myClsf->CanBeON(aS);
482 aExp.Init(aF, TopAbs_EDGE);
483 for (; aExp.More(); aExp.Next()) {
484 const TopoDS_Shape& aE=aExp.Current();
485 bIsConformState=myMSS.Contains(aE);
486 if (!bIsConformState) {
487 break;// edge has non-conformed state
490 aSt=myMSS.FindFromKey(aE);
491 aSC.AppendState(aSt);
495 if (!bIsConformState) {
496 continue; // edge has non-conformed state,skip face
499 InnerPoints(aF, aLP);
504 bIsConformState=Standard_True;
506 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
508 if (iCnt > myNbPntsMax) {
513 const gp_Pnt& aP=aIt.Value();
517 iErr=myClsf->ErrorStatus();
519 myErrorStatus=40; // point can not be classified
525 bIsToBreak=aSC.AppendState(aSt);
533 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
534 if (myShapeType==TopAbs_FACE) {
535 if (bIsConformState) {
539 else if (bIsConformState || aSt==TopAbs_ON) {
542 }// for (i=1; i<=aNb; ++i) next face
544 //=======================================================================
545 //function : ProcessSolids
547 //=======================================================================
548 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
552 Standard_Boolean bIsConformState;
553 Standard_Integer i, aNbS, j, aNbF;
554 TopTools_IndexedMapOfShape aM, aMF;
557 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
559 for (i=1; i<=aNbS; ++i) {
560 GEOMAlgo_StateCollector aSC;
562 const TopoDS_Shape& aSd=aM(i);
564 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
566 for (j=1; j<=aNbF; ++j) {
567 const TopoDS_Shape& aF=aMF(j);
568 bIsConformState=myMSS.Contains(aF);
569 if (!bIsConformState) {
570 break;// face has non-conformed state
573 aSt=myMSS.FindFromKey(aF);
574 aSC.AppendState(aSt);
578 if (!bIsConformState) {
579 continue; // face has non-conformed state,skip solid
584 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
585 if (bIsConformState) {
591 //=======================================================================
592 //function : InnerPoints
594 //=======================================================================
595 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
596 GEOMAlgo_ListOfPnt& aLP)
600 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
601 TopLoc_Location aLoc;
602 Handle(Poly_Triangulation) aTRF;
603 TColStd_MapOfInteger aMBN;
604 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
605 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
610 aTRF=BRep_Tool::Triangulation(aF, aLoc);
612 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
613 myWarningStatus=20; // no triangulation found
616 aTRF=BRep_Tool::Triangulation(aF, aLoc);
619 const gp_Trsf& aTrsf=aLoc.Transformation();
620 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
621 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
623 // map link/nbtriangles
626 for (j=j1; j<=j2; ++j) {
627 const Poly_Triangle& aTr=aTrs(j);
628 aTr.Get(n[0], n[1], n[2]);
630 for (k=0; k<3; ++k) {
631 GEOMAlgo_PassKey aPK;
633 aPK.SetIds(n[k], n[k+1]);
634 if (aMPKI.IsBound(aPK)) {
635 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
644 // boundary nodes aMBN
645 aNbLinks=aMPKI.Extent();
646 aIt.Initialize(aMPKI);
647 for (; aIt.More(); aIt.Next()) {
650 const GEOMAlgo_PassKey& aPK=aIt.Key();
654 pIds=(Standard_Integer*)aPK.Key();
655 for (k=1; k<3; ++k) {
656 aNx=*(pIds+aNbMax-k);
660 aNx=(Standard_Integer)aPK.Id(1);
662 aNx=(Standard_Integer)aPK.Id(2);
668 // inner nodes=all_nodes - boundary_nodes
671 for (j=j1; j<=j2; ++j) {
672 if (!aMBN.Contains(j)) {
673 aP=aNodes(j).Transformed(aTrsf);
680 if (!aNb && myNbPntsMin) {
681 // try to fill it yourself
682 Standard_Boolean bIsDone;
683 Standard_Integer aN1, aN2;
684 Handle(Geom_Surface) aS;
685 GeomAdaptor_Surface aGAS;
686 GeomAbs_SurfaceType aType;
688 aS=BRep_Tool::Surface(aF);
690 aType=aGAS.GetType();
691 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
693 aNbLinks=aMPKI.Extent();
694 aIt.Initialize(aMPKI);
695 for (; aIt.More(); aIt.Next()) {
698 // take the first having occured inner link
700 const GEOMAlgo_PassKey& aPK=aIt.Key();
704 pIds=(Standard_Integer*)aPK.Key();
705 aN1=*(pIds+aNbMax-1);
706 aN2=*(pIds+aNbMax-2);
709 aN1=(Standard_Integer)aPK.Id(1);
710 aN2=(Standard_Integer)aPK.Id(2);
712 aP1=aNodes(aN1).Transformed(aTrsf);
713 aP2=aNodes(aN2).Transformed(aTrsf);
715 if (aType==GeomAbs_Cylinder) {
716 Standard_Real aTolSM;
719 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
720 aCyl=aGAS.Cylinder();
721 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
726 BRepLib_MakeEdge aBME(aP1, aP2);
727 bIsDone=aBME.IsDone();
729 myErrorStatus=30; //can not obtain the line fron the link
733 const TopoDS_Shape& aSx=aBME.Shape();
734 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
736 InnerPoints(aE, myNbPntsMin, aLP);
739 }// for (; aIt.More(); aIt.Next())
740 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
741 }// if (!aNb && myNbPntsMin) {
743 //=======================================================================
744 //function : InnerPoints
746 //=======================================================================
747 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
748 GEOMAlgo_ListOfPnt& aLP)
752 Standard_Integer j, aNbNodes, aIndex, aNb;
753 Handle(Poly_PolygonOnTriangulation) aPTE;
754 Handle(Poly_Triangulation) aTRE;
755 TopLoc_Location aLoc;
759 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
760 if (aTRE.IsNull() || aPTE.IsNull()) {
761 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
763 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
764 myErrorStatus=20; // no triangulation found
767 aPE = BRep_Tool::Polygon3D(aE, aLoc);
769 const gp_Trsf& aTrsf=aLoc.Transformation();
770 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
772 aNbNodes=aPE->NbNodes();
773 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
774 for (j=low+1; j<up; ++j) {
775 aP=aNodes(j).Transformed(aTrsf);
780 const gp_Trsf& aTrsf=aLoc.Transformation();
781 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
783 aNbNodes=aPTE->NbNodes();
784 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
785 for (j=2; j<aNbNodes; ++j) {
787 aP=aNodes(aIndex).Transformed(aTrsf);
793 if (!aNb && myNbPntsMin) {
794 // try to fill it yourself
795 InnerPoints(aE, myNbPntsMin, aLP);
799 //=======================================================================
800 //function : InnerPoints
802 //=======================================================================
803 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
804 const Standard_Integer aNbPntsMin,
805 GEOMAlgo_ListOfPnt& aLP)
807 // try to fill it yourself
808 Standard_Boolean bInf1, bInf2;
809 Standard_Integer j, aNbT;
810 Standard_Real dT, aT, aT1, aT2;
812 Handle(Geom_Curve) aC3D;
814 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
819 bInf1=Precision::IsNegativeInfinite(aT1);
820 bInf2=Precision::IsPositiveInfinite(aT2);
821 if (bInf1 || bInf2) {
827 for (j=1; j<=aNbPntsMin; ++j) {
839 // 12 -unallowed type of sub-shapes
840 // 13 -unallowed state
841 // 15 -unallowed surface type
842 // 20- no triangulation found
843 // 30- can not obtain the line from the link
844 // 40- point can not be classified
845 // 41- invalid data for classifier