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_FinderShapeOn2.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>
45 #include <Geom_Curve.hxx>
46 #include <Geom_Surface.hxx>
47 #include <GeomAdaptor_Surface.hxx>
48 #include <GeomAbs_SurfaceType.hxx>
49 #include <GeomAdaptor_Curve.hxx>
50 #include <GeomAbs_CurveType.hxx>
52 #include <TopAbs_State.hxx>
54 #include <TopLoc_Location.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Edge.hxx>
62 #include <TopExp_Explorer.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
66 #include <BRep_Tool.hxx>
67 #include <BRepLib_MakeEdge.hxx>
69 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
71 #include <GEOMAlgo_SurfaceTools.hxx>
72 #include <GEOMAlgo_StateCollector.hxx>
74 #include <GEOMAlgo_PassKey.hxx>
75 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
76 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
78 //=======================================================================
79 //function : GEOMAlgo_FinderShapeOn1
81 //=======================================================================
82 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
87 myShapeType=TopAbs_VERTEX;
88 myState=GEOMAlgo_ST_UNKNOWN;
92 //=======================================================================
95 //=======================================================================
96 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
99 //=======================================================================
102 //=======================================================================
103 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
107 //=======================================================================
110 //=======================================================================
111 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
115 //=======================================================================
116 //function : SetShapeType
118 //=======================================================================
119 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
123 //=======================================================================
124 //function : ShapeType
126 //=======================================================================
127 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
131 //=======================================================================
132 //function : SetState
134 //=======================================================================
135 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
139 //=======================================================================
142 //=======================================================================
143 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
147 //=======================================================================
148 //function : SetNbPntsMin
150 //=======================================================================
151 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
155 //=======================================================================
156 //function : NbPntsMin
158 //=======================================================================
159 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
163 //=======================================================================
164 //function : SetNbPntsMax
166 //=======================================================================
167 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
171 //=======================================================================
172 //function : NbPntsMax
174 //=======================================================================
175 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
179 //=======================================================================
182 //=======================================================================
183 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
187 //=======================================================================
190 //=======================================================================
191 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
193 Standard_Integer i, aNb;
194 TopTools_ListOfShape* pL;
196 pL=(TopTools_ListOfShape*) &myLS;
200 for (i=1; i<=aNb; ++i) {
201 const TopoDS_Shape& aS=myMSS.FindKey(i);
202 if (aS.ShapeType()==myShapeType) {
208 //=======================================================================
211 //=======================================================================
212 void GEOMAlgo_FinderShapeOn2::Perform()
224 myClsf->SetTolerance(myTolerance);
231 if (myShapeType==TopAbs_VERTEX) {
240 if (myShapeType==TopAbs_EDGE) {
249 if (myShapeType==TopAbs_FACE) {
257 //=======================================================================
258 //function : CheckData
260 //=======================================================================
261 void GEOMAlgo_FinderShapeOn2::CheckData()
263 Standard_Integer iErr;
267 if(myClsf.IsNull()) {
268 myErrorStatus=10; // myClsf=NULL
273 iErr=myClsf->ErrorStatus();
275 myErrorStatus=41; // invalid data for classifier
279 if (myShape.IsNull()) {
280 myErrorStatus=11; // myShape=NULL
284 if (!(myShapeType==TopAbs_VERTEX ||
285 myShapeType==TopAbs_EDGE ||
286 myShapeType==TopAbs_FACE ||
287 myShapeType==TopAbs_SOLID)) {
288 myErrorStatus=12; // unallowed subshape type
292 if (myState==GEOMAlgo_ST_UNKNOWN ||
293 myState==GEOMAlgo_ST_INOUT) {
294 myErrorStatus=13; // unallowed state type
298 //=======================================================================
299 //function : ProcessVertices
301 //=======================================================================
302 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
306 Standard_Boolean bIsConformState;
307 Standard_Integer i, aNb, iErr;
309 TopTools_IndexedMapOfShape aM;
312 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
314 for (i=1; i<=aNb; ++i) {
315 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
316 aP=BRep_Tool::Pnt(aV);
320 iErr=myClsf->ErrorStatus();
322 myErrorStatus=40; // point can not be classified
327 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
329 if (myShapeType==TopAbs_VERTEX){
330 if (bIsConformState) {
334 else if (bIsConformState || aSt==TopAbs_ON) {
339 //=======================================================================
340 //function : ProcessEdges
342 //=======================================================================
343 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
347 Standard_Boolean bIsConformState, bIsToBreak;
348 Standard_Integer i, aNb, iCnt, iErr;
350 TopTools_IndexedMapOfShape aM;
351 TopExp_Explorer aExp;
352 GEOMAlgo_ListIteratorOfListOfPnt aIt;
354 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
356 for (i=1; i<=aNb; ++i) {
357 GEOMAlgo_ListOfPnt aLP;
358 GEOMAlgo_StateCollector aSC;
360 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
362 aExp.Init(aE, TopAbs_VERTEX);
363 for (; aExp.More(); aExp.Next()) {
364 const TopoDS_Shape& aV=aExp.Current();
366 bIsConformState=myMSS.Contains(aV);
367 if (!bIsConformState) {
368 break;// vertex has non-conformed state
371 aSt=myMSS.FindFromKey(aV);
372 aSC.AppendState(aSt);
376 if (!bIsConformState) {
377 continue; // vertex has non-conformed state,skip edge
380 if (BRep_Tool::Degenerated(aE)) {
385 if (myState==GEOMAlgo_ST_ON) {
386 Standard_Boolean bCanBeON;
387 Standard_Real aT1, aT2;
388 Handle(Geom_Curve) aC;
390 aC=BRep_Tool::Curve(aE, aT1, aT2);
391 bCanBeON=myClsf->CanBeON(aC);
397 InnerPoints(aE, aLP);
402 bIsConformState=Standard_True;
404 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
406 if (iCnt > myNbPntsMax) {
411 const gp_Pnt& aP=aIt.Value();
415 iErr=myClsf->ErrorStatus();
417 myErrorStatus=40; // point can not be classified
423 bIsToBreak=aSC.AppendState(aSt);
431 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
432 if (myShapeType==TopAbs_EDGE) {
433 if (bIsConformState) {
437 else if (bIsConformState || aSt==TopAbs_ON) {
440 } // for (i=1; i<=aNb; ++i) next edge
442 //=======================================================================
443 //function : ProcessFaces
445 //=======================================================================
446 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
450 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
451 Standard_Integer i, aNbF, iCnt, iErr;
453 TopTools_IndexedMapOfShape aM;
454 TopExp_Explorer aExp;
455 GEOMAlgo_ListIteratorOfListOfPnt aIt;
457 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
459 for (i=1; i<=aNbF; ++i) {
460 GEOMAlgo_StateCollector aSC;
461 GEOMAlgo_ListOfPnt aLP;
463 const TopoDS_Face& aF=TopoDS::Face(aM(i));
465 if (myState==GEOMAlgo_ST_ON) {
466 Handle(Geom_Surface) aS;
468 aS=BRep_Tool::Surface(aF);
469 bCanBeON=myClsf->CanBeON(aS);
475 aExp.Init(aF, TopAbs_EDGE);
476 for (; aExp.More(); aExp.Next()) {
477 const TopoDS_Shape& aE=aExp.Current();
478 bIsConformState=myMSS.Contains(aE);
479 if (!bIsConformState) {
480 break;// edge has non-conformed state
483 aSt=myMSS.FindFromKey(aE);
484 aSC.AppendState(aSt);
488 if (!bIsConformState) {
489 continue; // edge has non-conformed state,skip face
492 InnerPoints(aF, aLP);
497 bIsConformState=Standard_True;
499 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
501 if (iCnt > myNbPntsMax) {
506 const gp_Pnt& aP=aIt.Value();
510 iErr=myClsf->ErrorStatus();
512 myErrorStatus=40; // point can not be classified
518 bIsToBreak=aSC.AppendState(aSt);
526 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
527 if (myShapeType==TopAbs_FACE) {
528 if (bIsConformState) {
532 else if (bIsConformState || aSt==TopAbs_ON) {
535 }// for (i=1; i<=aNb; ++i) next face
537 //=======================================================================
538 //function : ProcessSolids
540 //=======================================================================
541 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
545 Standard_Boolean bIsConformState;
546 Standard_Integer i, aNbS, j, aNbF;
547 TopTools_IndexedMapOfShape aM, aMF;
550 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
552 for (i=1; i<=aNbS; ++i) {
553 GEOMAlgo_StateCollector aSC;
555 const TopoDS_Shape& aSd=aM(i);
557 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
559 for (j=1; j<=aNbF; ++j) {
560 const TopoDS_Shape& aF=aMF(j);
561 bIsConformState=myMSS.Contains(aF);
562 if (!bIsConformState) {
563 break;// face has non-conformed state
566 aSt=myMSS.FindFromKey(aF);
567 aSC.AppendState(aSt);
571 if (!bIsConformState) {
572 continue; // face has non-conformed state,skip solid
577 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
578 if (bIsConformState) {
584 //=======================================================================
585 //function : InnerPoints
587 //=======================================================================
588 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
589 GEOMAlgo_ListOfPnt& aLP)
593 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
594 TopLoc_Location aLoc;
595 Handle(Poly_Triangulation) aTRF;
596 TColStd_MapOfInteger aMBN;
597 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
598 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
603 aTRF=BRep_Tool::Triangulation(aF, aLoc);
605 myErrorStatus=20; // no triangulation found
609 const gp_Trsf& aTrsf=aLoc.Transformation();
610 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
611 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
613 // map link/nbtriangles
616 for (j=j1; j<=j2; ++j) {
617 const Poly_Triangle& aTr=aTrs(j);
618 aTr.Get(n[0], n[1], n[2]);
620 for (k=0; k<3; ++k) {
621 GEOMAlgo_PassKey aPK;
623 aPK.SetIds(n[k], n[k+1]);
624 if (aMPKI.IsBound(aPK)) {
625 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
634 // boundary nodes aMBN
635 aNbLinks=aMPKI.Extent();
636 aIt.Initialize(aMPKI);
637 for (; aIt.More(); aIt.Next()) {
640 const GEOMAlgo_PassKey& aPK=aIt.Key();
644 pIds=(Standard_Integer*)aPK.Key();
645 for (k=1; k<3; ++k) {
646 aNx=*(pIds+aNbMax-k);
650 aNx=(Standard_Integer)aPK.Id(1);
652 aNx=(Standard_Integer)aPK.Id(2);
658 // inner nodes=all_nodes - boundary_nodes
661 for (j=j1; j<=j2; ++j) {
662 if (!aMBN.Contains(j)) {
663 aP=aNodes(j).Transformed(aTrsf);
670 if (!aNb && myNbPntsMin) {
671 // try to fill it yourself
672 Standard_Boolean bIsDone;
673 Standard_Integer aN1, aN2;
674 Handle(Geom_Surface) aS;
675 GeomAdaptor_Surface aGAS;
676 GeomAbs_SurfaceType aType;
678 aS=BRep_Tool::Surface(aF);
680 aType=aGAS.GetType();
681 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
683 aNbLinks=aMPKI.Extent();
684 aIt.Initialize(aMPKI);
685 for (; aIt.More(); aIt.Next()) {
688 // take the first having occured inner link
690 const GEOMAlgo_PassKey& aPK=aIt.Key();
694 pIds=(Standard_Integer*)aPK.Key();
695 aN1=*(pIds+aNbMax-1);
696 aN2=*(pIds+aNbMax-2);
699 aN1=(Standard_Integer)aPK.Id(1);
700 aN2=(Standard_Integer)aPK.Id(2);
702 aP1=aNodes(aN1).Transformed(aTrsf);
703 aP2=aNodes(aN2).Transformed(aTrsf);
705 if (aType==GeomAbs_Cylinder) {
706 Standard_Real aTolSM;
709 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
710 aCyl=aGAS.Cylinder();
711 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
716 BRepLib_MakeEdge aBME(aP1, aP2);
717 bIsDone=aBME.IsDone();
719 myErrorStatus=30; //can not obtain the line fron the link
723 const TopoDS_Shape& aSx=aBME.Shape();
724 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
726 InnerPoints(aE, myNbPntsMin, aLP);
729 }// for (; aIt.More(); aIt.Next())
730 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
731 }// if (!aNb && myNbPntsMin) {
733 //=======================================================================
734 //function : InnerPoints
736 //=======================================================================
737 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
738 GEOMAlgo_ListOfPnt& aLP)
742 Standard_Integer j, aNbNodes, aIndex, aNb;
743 Handle(Poly_PolygonOnTriangulation) aPTE;
744 Handle(Poly_Triangulation) aTRE;
745 TopLoc_Location aLoc;
749 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
750 if (aTRE.IsNull() || aPTE.IsNull()) {
751 myErrorStatus=20; // no triangulation found
755 const gp_Trsf& aTrsf=aLoc.Transformation();
756 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
758 aNbNodes=aPTE->NbNodes();
759 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
760 for (j=2; j<aNbNodes; ++j) {
762 aP=aNodes(aIndex).Transformed(aTrsf);
767 if (!aNb && myNbPntsMin) {
768 // try to fill it yourself
769 InnerPoints(aE, myNbPntsMin, aLP);
774 //=======================================================================
775 //function : InnerPoints
777 //=======================================================================
778 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
779 const Standard_Integer aNbPntsMin,
780 GEOMAlgo_ListOfPnt& aLP)
782 // try to fill it yourself
783 Standard_Boolean bInf1, bInf2;
784 Standard_Integer j, aNbT;
785 Standard_Real dT, aT, aT1, aT2;
787 Handle(Geom_Curve) aC3D;
789 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
794 bInf1=Precision::IsNegativeInfinite(aT1);
795 bInf2=Precision::IsPositiveInfinite(aT2);
796 if (bInf1 || bInf2) {
802 for (j=1; j<=aNbPntsMin; ++j) {
814 // 12 -unallowed type of subshapes
815 // 13 -unallowed state
816 // 15 -unallowed surface type
817 // 20- no triangulation found
818 // 30- can not obtain the line from the link
819 // 40- point can not be classified
820 // 41- invalid data for classifier