1 // Copyright (C) 2007-2008 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
22 // File: GEOMAlgo_FinderShapeOn1.cxx
23 // Created: Fri Mar 4 10:31:06 2005
24 // Author: Peter KURNEV
27 #include <GEOMAlgo_FinderShapeOn1.ixx>
31 #include <Precision.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <TColStd_MapOfInteger.hxx>
35 #include <gp_Trsf.hxx>
36 #include <gp_Cylinder.hxx>
39 #include <TColgp_Array1OfPnt.hxx>
41 #include <Poly_Array1OfTriangle.hxx>
42 #include <Poly_Triangle.hxx>
43 #include <Poly_PolygonOnTriangulation.hxx>
44 #include <Poly_Triangulation.hxx>
45 #include <Poly_Polygon3D.hxx>
47 #include <Geom_Curve.hxx>
48 #include <Geom_Surface.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomAbs_SurfaceType.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <GeomAbs_CurveType.hxx>
54 #include <TopAbs_State.hxx>
56 #include <TopLoc_Location.hxx>
58 #include <TopoDS_Shape.hxx>
59 #include <TopoDS_Vertex.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Edge.hxx>
64 #include <TopExp_Explorer.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <BRep_Tool.hxx>
69 #include <BRepLib_MakeEdge.hxx>
71 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
73 #include <GEOMAlgo_SurfaceTools.hxx>
74 #include <GEOMAlgo_StateCollector.hxx>
75 #include <GEOMAlgo_FinderShapeOn.hxx>
77 #include <GEOMAlgo_PassKey.hxx>
78 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
79 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
81 //=======================================================================
82 //function : GEOMAlgo_FinderShapeOn1
84 //=======================================================================
85 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
90 myShapeType=TopAbs_VERTEX;
91 myState=GEOMAlgo_ST_UNKNOWN;
95 //=======================================================================
98 //=======================================================================
99 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
102 //=======================================================================
103 //function : SetSurface
105 //=======================================================================
106 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
110 //=======================================================================
113 //=======================================================================
114 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
118 //=======================================================================
119 //function : SetShapeType
121 //=======================================================================
122 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
126 //=======================================================================
127 //function : ShapeType
129 //=======================================================================
130 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
134 //=======================================================================
135 //function : SetState
137 //=======================================================================
138 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
142 //=======================================================================
145 //=======================================================================
146 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
150 //=======================================================================
151 //function : SetNbPntsMin
153 //=======================================================================
154 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
158 //=======================================================================
159 //function : NbPntsMin
161 //=======================================================================
162 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
166 //=======================================================================
167 //function : SetNbPntsMax
169 //=======================================================================
170 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
174 //=======================================================================
175 //function : NbPntsMax
177 //=======================================================================
178 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
182 //=======================================================================
185 //=======================================================================
186 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
190 //=======================================================================
193 //=======================================================================
194 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
196 Standard_Integer i, aNb;
197 TopTools_ListOfShape* pL;
199 pL=(TopTools_ListOfShape*) &myLS;
203 for (i=1; i<=aNb; ++i) {
204 const TopoDS_Shape& aS=myMSS.FindKey(i);
205 if (aS.ShapeType()==myShapeType) {
211 //=======================================================================
214 //=======================================================================
215 void GEOMAlgo_FinderShapeOn1::Perform()
232 if (myShapeType==TopAbs_VERTEX) {
241 if (myShapeType==TopAbs_EDGE) {
250 if (myShapeType==TopAbs_FACE) {
258 //=======================================================================
259 //function : ProcessVertices
261 //=======================================================================
262 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
266 Standard_Boolean bIsConformState;
267 Standard_Integer i, aNb;
269 TopTools_IndexedMapOfShape aM;
272 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
274 for (i=1; i<=aNb; ++i) {
275 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
276 aP=BRep_Tool::Pnt(aV);
278 aSt = GetPointState( aP );
279 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
281 if (myShapeType==TopAbs_VERTEX){
282 if (bIsConformState) {
286 else if (bIsConformState || aSt==TopAbs_ON) {
291 //=======================================================================
292 //function : ProcessEdges
294 //=======================================================================
295 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
299 Standard_Boolean bIsConformState, bIsToBreak;
300 Standard_Integer i, aNb, iCnt;
302 TopTools_IndexedMapOfShape aM;
303 TopExp_Explorer aExp;
304 GEOMAlgo_ListIteratorOfListOfPnt aIt;
305 GeomAbs_SurfaceType aType1;
307 aType1=myGAS.GetType();
309 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
311 for (i=1; i<=aNb; ++i) {
312 GEOMAlgo_ListOfPnt aLP;
313 GEOMAlgo_StateCollector aSC;
315 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
317 aExp.Init(aE, TopAbs_VERTEX);
318 for (; aExp.More(); aExp.Next()) {
319 const TopoDS_Shape& aV=aExp.Current();
321 bIsConformState=myMSS.Contains(aV);
322 if (!bIsConformState) {
323 break;// vertex has non-conformed state
326 aSt=myMSS.FindFromKey(aV);
327 aSC.AppendState(aSt);
331 if (!bIsConformState) {
332 continue; // vertex has non-conformed state,skip edge
335 if (BRep_Tool::Degenerated(aE)) {
340 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
341 Standard_Real aT1, aT2;
342 Handle(Geom_Curve) aC;
343 GeomAdaptor_Curve aGAC;
344 GeomAbs_CurveType aType2;
346 aC=BRep_Tool::Curve(aE, aT1, aT2);
349 aType2=aGAC.GetType();
350 if (aType2==GeomAbs_Line) {
355 InnerPoints(aE, aLP);
360 bIsConformState=Standard_True;
362 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
364 if (iCnt > myNbPntsMax) {
369 const gp_Pnt& aP=aIt.Value();
370 aSt = GetPointState( aP );
371 bIsToBreak=aSC.AppendState(aSt);
379 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
380 if (myShapeType==TopAbs_EDGE) {
381 if (bIsConformState) {
385 else if (bIsConformState || aSt==TopAbs_ON) {
388 } // for (i=1; i<=aNb; ++i) next edge
390 //=======================================================================
391 //function : ProcessFaces
393 //=======================================================================
394 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
398 Standard_Boolean bIsConformState, bIsToBreak;
399 Standard_Integer i, aNbF, iCnt;
401 TopTools_IndexedMapOfShape aM;
402 TopExp_Explorer aExp;
403 GEOMAlgo_ListIteratorOfListOfPnt aIt;
404 GeomAbs_SurfaceType aType1, aType2;
406 aType1=myGAS.GetType();
408 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
410 for (i=1; i<=aNbF; ++i) {
411 GEOMAlgo_StateCollector aSC;
412 GEOMAlgo_ListOfPnt aLP;
414 const TopoDS_Face& aF=TopoDS::Face(aM(i));
416 if (myState==GEOMAlgo_ST_ON) {
417 Handle(Geom_Surface) aS;
418 GeomAdaptor_Surface aGAS;
420 aS=BRep_Tool::Surface(aF);
422 aType2=aGAS.GetType();
423 if (aType2!=aType1) {
428 aExp.Init(aF, TopAbs_EDGE);
429 for (; aExp.More(); aExp.Next()) {
430 const TopoDS_Shape& aE=aExp.Current();
431 bIsConformState=myMSS.Contains(aE);
432 if (!bIsConformState) {
433 break;// edge has non-conformed state
436 aSt=myMSS.FindFromKey(aE);
437 aSC.AppendState(aSt);
441 if (!bIsConformState) {
442 continue; // edge has non-conformed state,skip face
445 InnerPoints(aF, aLP);
450 bIsConformState=Standard_True;
452 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
454 if (iCnt > myNbPntsMax) {
459 const gp_Pnt& aP=aIt.Value();
460 aSt = GetPointState( aP );
461 bIsToBreak=aSC.AppendState(aSt);
469 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
470 if (myShapeType==TopAbs_FACE) {
471 if (bIsConformState) {
475 else if (bIsConformState || aSt==TopAbs_ON) {
478 }// for (i=1; i<=aNb; ++i) next face
480 //=======================================================================
481 //function : ProcessSolids
483 //=======================================================================
484 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
488 Standard_Boolean bIsConformState;
489 Standard_Integer i, aNbS, j, aNbF;
490 TopTools_IndexedMapOfShape aM, aMF;
493 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
495 for (i=1; i<=aNbS; ++i) {
496 GEOMAlgo_StateCollector aSC;
498 const TopoDS_Shape& aSd=aM(i);
500 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
502 for (j=1; j<=aNbF; ++j) {
503 const TopoDS_Shape& aF=aMF(j);
504 bIsConformState=myMSS.Contains(aF);
505 if (!bIsConformState) {
506 break;// face has non-conformed state
509 aSt=myMSS.FindFromKey(aF);
510 aSC.AppendState(aSt);
514 if (!bIsConformState) {
515 continue; // face has non-conformed state,skip solid
520 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
521 if (bIsConformState) {
527 //=======================================================================
528 //function : InnerPoints
530 //=======================================================================
531 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
532 GEOMAlgo_ListOfPnt& aLP)
536 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
537 TopLoc_Location aLoc;
538 Handle(Poly_Triangulation) aTRF;
539 TColStd_MapOfInteger aMBN;
540 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
541 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
546 aTRF=BRep_Tool::Triangulation(aF, aLoc);
548 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
549 myWarningStatus=20; // no triangulation found
552 aTRF=BRep_Tool::Triangulation(aF, aLoc);
555 const gp_Trsf& aTrsf=aLoc.Transformation();
556 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
557 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
559 // map link/nbtriangles
562 for (j=j1; j<=j2; ++j) {
563 const Poly_Triangle& aTr=aTrs(j);
564 aTr.Get(n[0], n[1], n[2]);
566 for (k=0; k<3; ++k) {
567 GEOMAlgo_PassKey aPK;
569 aPK.SetIds(n[k], n[k+1]);
570 if (aMPKI.IsBound(aPK)) {
571 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
580 // boundary nodes aMBN
581 aNbLinks=aMPKI.Extent();
582 aIt.Initialize(aMPKI);
583 for (; aIt.More(); aIt.Next()) {
586 const GEOMAlgo_PassKey& aPK=aIt.Key();
590 pIds=(Standard_Integer*)aPK.Key();
591 for (k=1; k<3; ++k) {
592 aNx=*(pIds+aNbMax-k);
596 aNx=(Standard_Integer)aPK.Id(1);
598 aNx=(Standard_Integer)aPK.Id(2);
604 // inner nodes=all_nodes - boundary_nodes
607 for (j=j1; j<=j2; ++j) {
608 if (!aMBN.Contains(j)) {
609 aP=aNodes(j).Transformed(aTrsf);
616 if (!aNb && myNbPntsMin) {
617 // try to fill it yourself
618 Standard_Boolean bIsDone;
619 Standard_Integer aN1, aN2;
620 Handle(Geom_Surface) aS;
621 GeomAdaptor_Surface aGAS;
622 GeomAbs_SurfaceType aType;
624 aS=BRep_Tool::Surface(aF);
626 aType=aGAS.GetType();
627 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
629 aNbLinks=aMPKI.Extent();
630 aIt.Initialize(aMPKI);
631 for (; aIt.More(); aIt.Next()) {
634 // take the first having occured inner link
636 const GEOMAlgo_PassKey& aPK=aIt.Key();
640 pIds=(Standard_Integer*)aPK.Key();
641 aN1=*(pIds+aNbMax-1);
642 aN2=*(pIds+aNbMax-2);
645 aN1=(Standard_Integer)aPK.Id(1);
646 aN2=(Standard_Integer)aPK.Id(2);
648 aP1=aNodes(aN1).Transformed(aTrsf);
649 aP2=aNodes(aN2).Transformed(aTrsf);
651 if (aType==GeomAbs_Cylinder) {
652 Standard_Real aTolSM;
655 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
656 aCyl=aGAS.Cylinder();
657 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
662 BRepLib_MakeEdge aBME(aP1, aP2);
663 bIsDone=aBME.IsDone();
665 myErrorStatus=30; //can not obtain the line fron the link
669 const TopoDS_Shape& aSx=aBME.Shape();
670 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
672 InnerPoints(aE, myNbPntsMin, aLP);
675 }// for (; aIt.More(); aIt.Next())
676 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
677 }// if (!aNb && myNbPntsMin) {
679 //=======================================================================
680 //function : InnerPoints
682 //=======================================================================
683 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
684 GEOMAlgo_ListOfPnt& aLP)
688 Standard_Integer j, aNbNodes, aIndex, aNb;
689 Handle(Poly_PolygonOnTriangulation) aPTE;
690 Handle(Poly_Triangulation) aTRE;
691 TopLoc_Location aLoc;
695 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
696 if (aTRE.IsNull() || aPTE.IsNull()) {
697 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
699 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
700 myErrorStatus=20; // no triangulation found
703 aPE = BRep_Tool::Polygon3D(aE, aLoc);
705 const gp_Trsf& aTrsf=aLoc.Transformation();
706 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
708 aNbNodes=aPE->NbNodes();
709 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
710 for (j=low+1; j<up; ++j) {
711 aP=aNodes(j).Transformed(aTrsf);
716 const gp_Trsf& aTrsf=aLoc.Transformation();
717 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
719 aNbNodes=aPTE->NbNodes();
720 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
721 for (j=2; j<aNbNodes; ++j) {
723 aP=aNodes(aIndex).Transformed(aTrsf);
729 if (!aNb && myNbPntsMin) {
730 // try to fill it yourself
731 InnerPoints(aE, myNbPntsMin, aLP);
735 //=======================================================================
736 //function : InnerPoints
738 //=======================================================================
739 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
740 const Standard_Integer aNbPntsMin,
741 GEOMAlgo_ListOfPnt& aLP)
743 // try to fill it yourself
744 Standard_Boolean bInf1, bInf2;
745 Standard_Integer j, aNbT;
746 Standard_Real dT, aT, aT1, aT2;
748 Handle(Geom_Curve) aC3D;
750 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
755 bInf1=Precision::IsNegativeInfinite(aT1);
756 bInf2=Precision::IsPositiveInfinite(aT2);
757 if (bInf1 || bInf2) {
763 for (j=1; j<=aNbPntsMin; ++j) {
770 //=======================================================================
771 //function : CheckData
773 //=======================================================================
774 void GEOMAlgo_FinderShapeOn1::CheckData()
778 if(mySurface.IsNull()) {
779 myErrorStatus=10; // mySurface=NULL
783 if (myShape.IsNull()) {
784 myErrorStatus=11; // myShape=NULL
788 if (!(myShapeType==TopAbs_VERTEX ||
789 myShapeType==TopAbs_EDGE ||
790 myShapeType==TopAbs_FACE ||
791 myShapeType==TopAbs_SOLID)) {
792 myErrorStatus=12; // unallowed subshape type
796 if (myState==GEOMAlgo_ST_UNKNOWN ||
797 myState==GEOMAlgo_ST_INOUT) {
798 myErrorStatus=13; // unallowed state type
802 GeomAbs_SurfaceType aType;
804 myGAS.Load(mySurface);
805 aType=myGAS.GetType();
806 if (!(aType==GeomAbs_Plane ||
807 aType==GeomAbs_Cylinder ||
808 aType==GeomAbs_Sphere)) {
809 myErrorStatus=14; // unallowed surface type
813 //=======================================================================
814 //function : GetPointState
816 //=======================================================================
818 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
821 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
829 // 10 -mySurface=NULL
831 // 12 -unallowed type of subshapes
832 // 13 -unallowed state
833 // 14 -unallowed surface type
834 // 15 -unallowed surface type
835 // 20- no triangulation found
836 // 30- can not obtain the line from the link
841 #include <OSD_Chronometer.hxx>
842 #include <Standard_Static.hxx>
844 Standard_STATIC(OSD_Chronometer, x_S_Chrono);
845 static void x_StartChrono();
846 static void x_StopChrono();
847 static Standard_Boolean x_IsToShow();
849 //=======================================================================
850 //function : x_StartChrono
852 //=======================================================================
856 x_S_Chrono().Reset();
857 x_S_Chrono().Start();
860 //=======================================================================
861 //function : x_StopChrono
863 //=======================================================================
867 Standard_Real Chrono;
869 x_S_Chrono().Show(Chrono);
870 printf(" Tps: %lf\n", Chrono);
871 //cout << "Tps: " << Chrono << endl;
874 //=======================================================================
875 //function : x_IsToShow
877 //=======================================================================
878 Standard_Boolean x_IsToShow()
880 Standard_Boolean bFlag=Standard_False;
882 char *xr=getenv ("STDCHRONO");
884 if (!strcmp (xr, "yes")) {