1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: GEOMAlgo_FinderShapeOn1.cxx
21 // Created: Fri Mar 4 10:31:06 2005
22 // Author: Peter KURNEV
26 #include <GEOMAlgo_FinderShapeOn1.ixx>
30 #include <Precision.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_MapOfInteger.hxx>
34 #include <gp_Trsf.hxx>
35 #include <gp_Cylinder.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
40 #include <Poly_Array1OfTriangle.hxx>
41 #include <Poly_Triangle.hxx>
42 #include <Poly_PolygonOnTriangulation.hxx>
43 #include <Poly_Triangulation.hxx>
44 #include <Poly_Polygon3D.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <GeomAdaptor_Surface.hxx>
49 #include <GeomAbs_SurfaceType.hxx>
50 #include <GeomAdaptor_Curve.hxx>
51 #include <GeomAbs_CurveType.hxx>
53 #include <TopAbs_State.hxx>
55 #include <TopLoc_Location.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Face.hxx>
60 #include <TopoDS_Edge.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <BRep_Tool.hxx>
68 #include <BRepLib_MakeEdge.hxx>
70 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
72 #include <GEOMAlgo_SurfaceTools.hxx>
73 #include <GEOMAlgo_StateCollector.hxx>
74 #include <GEOMAlgo_FinderShapeOn.hxx>
76 #include <GEOMAlgo_PassKey.hxx>
77 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
78 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
80 //=======================================================================
81 //function : GEOMAlgo_FinderShapeOn1
83 //=======================================================================
84 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
89 myShapeType=TopAbs_VERTEX;
90 myState=GEOMAlgo_ST_UNKNOWN;
94 //=======================================================================
97 //=======================================================================
98 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
101 //=======================================================================
102 //function : SetSurface
104 //=======================================================================
105 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
109 //=======================================================================
112 //=======================================================================
113 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
117 //=======================================================================
118 //function : SetShapeType
120 //=======================================================================
121 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
125 //=======================================================================
126 //function : ShapeType
128 //=======================================================================
129 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
133 //=======================================================================
134 //function : SetState
136 //=======================================================================
137 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
141 //=======================================================================
144 //=======================================================================
145 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
149 //=======================================================================
150 //function : SetNbPntsMin
152 //=======================================================================
153 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
157 //=======================================================================
158 //function : NbPntsMin
160 //=======================================================================
161 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
165 //=======================================================================
166 //function : SetNbPntsMax
168 //=======================================================================
169 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
173 //=======================================================================
174 //function : NbPntsMax
176 //=======================================================================
177 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
181 //=======================================================================
184 //=======================================================================
185 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
189 //=======================================================================
192 //=======================================================================
193 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
195 Standard_Integer i, aNb;
196 TopTools_ListOfShape* pL;
198 pL=(TopTools_ListOfShape*) &myLS;
202 for (i=1; i<=aNb; ++i) {
203 const TopoDS_Shape& aS=myMSS.FindKey(i);
204 if (aS.ShapeType()==myShapeType) {
210 //=======================================================================
213 //=======================================================================
214 void GEOMAlgo_FinderShapeOn1::Perform()
231 if (myShapeType==TopAbs_VERTEX) {
240 if (myShapeType==TopAbs_EDGE) {
249 if (myShapeType==TopAbs_FACE) {
257 //=======================================================================
258 //function : ProcessVertices
260 //=======================================================================
261 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
265 Standard_Boolean bIsConformState;
266 Standard_Integer i, aNb;
268 TopTools_IndexedMapOfShape aM;
271 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
273 for (i=1; i<=aNb; ++i) {
274 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
275 aP=BRep_Tool::Pnt(aV);
277 aSt = GetPointState( aP );
278 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
280 if (myShapeType==TopAbs_VERTEX){
281 if (bIsConformState) {
285 else if (bIsConformState || aSt==TopAbs_ON) {
290 //=======================================================================
291 //function : ProcessEdges
293 //=======================================================================
294 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
298 Standard_Boolean bIsConformState, bIsToBreak;
299 Standard_Integer i, aNb, iCnt;
301 TopTools_IndexedMapOfShape aM;
302 TopExp_Explorer aExp;
303 GEOMAlgo_ListIteratorOfListOfPnt aIt;
304 GeomAbs_SurfaceType aType1;
306 aType1=myGAS.GetType();
308 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
310 for (i=1; i<=aNb; ++i) {
311 GEOMAlgo_ListOfPnt aLP;
312 GEOMAlgo_StateCollector aSC;
314 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
316 aExp.Init(aE, TopAbs_VERTEX);
317 for (; aExp.More(); aExp.Next()) {
318 const TopoDS_Shape& aV=aExp.Current();
320 bIsConformState=myMSS.Contains(aV);
321 if (!bIsConformState) {
322 break;// vertex has non-conformed state
325 aSt=myMSS.FindFromKey(aV);
326 aSC.AppendState(aSt);
330 if (!bIsConformState) {
331 continue; // vertex has non-conformed state,skip edge
334 if (BRep_Tool::Degenerated(aE)) {
339 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
340 Standard_Real aT1, aT2;
341 Handle(Geom_Curve) aC;
342 GeomAdaptor_Curve aGAC;
343 GeomAbs_CurveType aType2;
345 aC=BRep_Tool::Curve(aE, aT1, aT2);
348 aType2=aGAC.GetType();
349 if (aType2==GeomAbs_Line) {
354 InnerPoints(aE, aLP);
359 bIsConformState=Standard_True;
361 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
363 if (iCnt > myNbPntsMax) {
368 const gp_Pnt& aP=aIt.Value();
369 aSt = GetPointState( aP );
370 bIsToBreak=aSC.AppendState(aSt);
378 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
379 if (myShapeType==TopAbs_EDGE) {
380 if (bIsConformState) {
384 else if (bIsConformState || aSt==TopAbs_ON) {
387 } // for (i=1; i<=aNb; ++i) next edge
389 //=======================================================================
390 //function : ProcessFaces
392 //=======================================================================
393 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
397 Standard_Boolean bIsConformState, bIsToBreak;
398 Standard_Integer i, aNbF, iCnt;
400 TopTools_IndexedMapOfShape aM;
401 TopExp_Explorer aExp;
402 GEOMAlgo_ListIteratorOfListOfPnt aIt;
403 GeomAbs_SurfaceType aType1, aType2;
405 aType1=myGAS.GetType();
407 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
409 for (i=1; i<=aNbF; ++i) {
410 GEOMAlgo_StateCollector aSC;
411 GEOMAlgo_ListOfPnt aLP;
413 const TopoDS_Face& aF=TopoDS::Face(aM(i));
415 if (myState==GEOMAlgo_ST_ON) {
416 Handle(Geom_Surface) aS;
417 GeomAdaptor_Surface aGAS;
419 aS=BRep_Tool::Surface(aF);
421 aType2=aGAS.GetType();
422 if (aType2!=aType1) {
427 aExp.Init(aF, TopAbs_EDGE);
428 for (; aExp.More(); aExp.Next()) {
429 const TopoDS_Shape& aE=aExp.Current();
430 bIsConformState=myMSS.Contains(aE);
431 if (!bIsConformState) {
432 break;// edge has non-conformed state
435 aSt=myMSS.FindFromKey(aE);
436 aSC.AppendState(aSt);
440 if (!bIsConformState) {
441 continue; // edge has non-conformed state,skip face
444 InnerPoints(aF, aLP);
449 bIsConformState=Standard_True;
451 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
453 if (iCnt > myNbPntsMax) {
458 const gp_Pnt& aP=aIt.Value();
459 aSt = GetPointState( aP );
460 bIsToBreak=aSC.AppendState(aSt);
468 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
469 if (myShapeType==TopAbs_FACE) {
470 if (bIsConformState) {
474 else if (bIsConformState || aSt==TopAbs_ON) {
477 }// for (i=1; i<=aNb; ++i) next face
479 //=======================================================================
480 //function : ProcessSolids
482 //=======================================================================
483 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
487 Standard_Boolean bIsConformState;
488 Standard_Integer i, aNbS, j, aNbF;
489 TopTools_IndexedMapOfShape aM, aMF;
492 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
494 for (i=1; i<=aNbS; ++i) {
495 GEOMAlgo_StateCollector aSC;
497 const TopoDS_Shape& aSd=aM(i);
499 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
501 for (j=1; j<=aNbF; ++j) {
502 const TopoDS_Shape& aF=aMF(j);
503 bIsConformState=myMSS.Contains(aF);
504 if (!bIsConformState) {
505 break;// face has non-conformed state
508 aSt=myMSS.FindFromKey(aF);
509 aSC.AppendState(aSt);
513 if (!bIsConformState) {
514 continue; // face has non-conformed state,skip solid
519 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
520 if (bIsConformState) {
526 //=======================================================================
527 //function : InnerPoints
529 //=======================================================================
530 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
531 GEOMAlgo_ListOfPnt& aLP)
535 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
536 TopLoc_Location aLoc;
537 Handle(Poly_Triangulation) aTRF;
538 TColStd_MapOfInteger aMBN;
539 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
540 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
545 aTRF=BRep_Tool::Triangulation(aF, aLoc);
547 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
548 myErrorStatus=20; // no triangulation found
551 aTRF=BRep_Tool::Triangulation(aF, aLoc);
554 const gp_Trsf& aTrsf=aLoc.Transformation();
555 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
556 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
558 // map link/nbtriangles
561 for (j=j1; j<=j2; ++j) {
562 const Poly_Triangle& aTr=aTrs(j);
563 aTr.Get(n[0], n[1], n[2]);
565 for (k=0; k<3; ++k) {
566 GEOMAlgo_PassKey aPK;
568 aPK.SetIds(n[k], n[k+1]);
569 if (aMPKI.IsBound(aPK)) {
570 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
579 // boundary nodes aMBN
580 aNbLinks=aMPKI.Extent();
581 aIt.Initialize(aMPKI);
582 for (; aIt.More(); aIt.Next()) {
585 const GEOMAlgo_PassKey& aPK=aIt.Key();
589 pIds=(Standard_Integer*)aPK.Key();
590 for (k=1; k<3; ++k) {
591 aNx=*(pIds+aNbMax-k);
595 aNx=(Standard_Integer)aPK.Id(1);
597 aNx=(Standard_Integer)aPK.Id(2);
603 // inner nodes=all_nodes - boundary_nodes
606 for (j=j1; j<=j2; ++j) {
607 if (!aMBN.Contains(j)) {
608 aP=aNodes(j).Transformed(aTrsf);
615 if (!aNb && myNbPntsMin) {
616 // try to fill it yourself
617 Standard_Boolean bIsDone;
618 Standard_Integer aN1, aN2;
619 Handle(Geom_Surface) aS;
620 GeomAdaptor_Surface aGAS;
621 GeomAbs_SurfaceType aType;
623 aS=BRep_Tool::Surface(aF);
625 aType=aGAS.GetType();
626 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
628 aNbLinks=aMPKI.Extent();
629 aIt.Initialize(aMPKI);
630 for (; aIt.More(); aIt.Next()) {
633 // take the first having occured inner link
635 const GEOMAlgo_PassKey& aPK=aIt.Key();
639 pIds=(Standard_Integer*)aPK.Key();
640 aN1=*(pIds+aNbMax-1);
641 aN2=*(pIds+aNbMax-2);
644 aN1=(Standard_Integer)aPK.Id(1);
645 aN2=(Standard_Integer)aPK.Id(2);
647 aP1=aNodes(aN1).Transformed(aTrsf);
648 aP2=aNodes(aN2).Transformed(aTrsf);
650 if (aType==GeomAbs_Cylinder) {
651 Standard_Real aTolSM;
654 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
655 aCyl=aGAS.Cylinder();
656 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
661 BRepLib_MakeEdge aBME(aP1, aP2);
662 bIsDone=aBME.IsDone();
664 myErrorStatus=30; //can not obtain the line fron the link
668 const TopoDS_Shape& aSx=aBME.Shape();
669 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
671 InnerPoints(aE, myNbPntsMin, aLP);
674 }// for (; aIt.More(); aIt.Next())
675 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
676 }// if (!aNb && myNbPntsMin) {
678 //=======================================================================
679 //function : InnerPoints
681 //=======================================================================
682 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
683 GEOMAlgo_ListOfPnt& aLP)
687 Standard_Integer j, aNbNodes, aIndex, aNb;
688 Handle(Poly_PolygonOnTriangulation) aPTE;
689 Handle(Poly_Triangulation) aTRE;
690 TopLoc_Location aLoc;
694 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
695 if (aTRE.IsNull() || aPTE.IsNull()) {
696 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
698 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
699 myErrorStatus=20; // no triangulation found
702 aPE = BRep_Tool::Polygon3D(aE, aLoc);
704 const gp_Trsf& aTrsf=aLoc.Transformation();
705 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
707 aNbNodes=aPE->NbNodes();
708 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
709 for (j=low+1; j<up; ++j) {
710 aP=aNodes(j).Transformed(aTrsf);
715 const gp_Trsf& aTrsf=aLoc.Transformation();
716 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
718 aNbNodes=aPTE->NbNodes();
719 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
720 for (j=2; j<aNbNodes; ++j) {
722 aP=aNodes(aIndex).Transformed(aTrsf);
728 if (!aNb && myNbPntsMin) {
729 // try to fill it yourself
730 InnerPoints(aE, myNbPntsMin, aLP);
734 //=======================================================================
735 //function : InnerPoints
737 //=======================================================================
738 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
739 const Standard_Integer aNbPntsMin,
740 GEOMAlgo_ListOfPnt& aLP)
742 // try to fill it yourself
743 Standard_Boolean bInf1, bInf2;
744 Standard_Integer j, aNbT;
745 Standard_Real dT, aT, aT1, aT2;
747 Handle(Geom_Curve) aC3D;
749 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
754 bInf1=Precision::IsNegativeInfinite(aT1);
755 bInf2=Precision::IsPositiveInfinite(aT2);
756 if (bInf1 || bInf2) {
762 for (j=1; j<=aNbPntsMin; ++j) {
769 //=======================================================================
770 //function : CheckData
772 //=======================================================================
773 void GEOMAlgo_FinderShapeOn1::CheckData()
777 if(mySurface.IsNull()) {
778 myErrorStatus=10; // mySurface=NULL
782 if (myShape.IsNull()) {
783 myErrorStatus=11; // myShape=NULL
787 if (!(myShapeType==TopAbs_VERTEX ||
788 myShapeType==TopAbs_EDGE ||
789 myShapeType==TopAbs_FACE ||
790 myShapeType==TopAbs_SOLID)) {
791 myErrorStatus=12; // unallowed subshape type
795 if (myState==GEOMAlgo_ST_UNKNOWN ||
796 myState==GEOMAlgo_ST_INOUT) {
797 myErrorStatus=13; // unallowed state type
801 GeomAbs_SurfaceType aType;
803 myGAS.Load(mySurface);
804 aType=myGAS.GetType();
805 if (!(aType==GeomAbs_Plane ||
806 aType==GeomAbs_Cylinder ||
807 aType==GeomAbs_Sphere)) {
808 myErrorStatus=14; // unallowed surface type
812 //=======================================================================
813 //function : GetPointState
815 //=======================================================================
817 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
820 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
828 // 10 -mySurface=NULL
830 // 12 -unallowed type of subshapes
831 // 13 -unallowed state
832 // 14 -unallowed surface type
833 // 15 -unallowed surface type
834 // 20- no triangulation found
835 // 30- can not obtain the line from the link
840 #include <OSD_Chronometer.hxx>
841 #include <Standard_Static.hxx>
843 Standard_STATIC(OSD_Chronometer, x_S_Chrono);
844 static void x_StartChrono();
845 static void x_StopChrono();
846 static Standard_Boolean x_IsToShow();
848 //=======================================================================
849 //function : x_StartChrono
851 //=======================================================================
855 x_S_Chrono().Reset();
856 x_S_Chrono().Start();
859 //=======================================================================
860 //function : x_StopChrono
862 //=======================================================================
866 Standard_Real Chrono;
868 x_S_Chrono().Show(Chrono);
869 printf(" Tps: %lf\n", Chrono);
870 //cout << "Tps: " << Chrono << endl;
873 //=======================================================================
874 //function : x_IsToShow
876 //=======================================================================
877 Standard_Boolean x_IsToShow()
879 Standard_Boolean bFlag=Standard_False;
881 char *xr=getenv ("STDCHRONO");
883 if (!strcmp (xr, "yes")) {