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>
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>
75 #include <GEOMAlgo_PassKey.hxx>
76 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
77 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
79 //=======================================================================
80 //function : GEOMAlgo_FinderShapeOn1
82 //=======================================================================
83 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
88 myShapeType=TopAbs_VERTEX;
89 myState=GEOMAlgo_ST_UNKNOWN;
93 //=======================================================================
96 //=======================================================================
97 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
100 //=======================================================================
103 //=======================================================================
104 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
108 //=======================================================================
111 //=======================================================================
112 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
116 //=======================================================================
117 //function : SetShapeType
119 //=======================================================================
120 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
124 //=======================================================================
125 //function : ShapeType
127 //=======================================================================
128 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
132 //=======================================================================
133 //function : SetState
135 //=======================================================================
136 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
140 //=======================================================================
143 //=======================================================================
144 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
148 //=======================================================================
149 //function : SetNbPntsMin
151 //=======================================================================
152 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
156 //=======================================================================
157 //function : NbPntsMin
159 //=======================================================================
160 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
164 //=======================================================================
165 //function : SetNbPntsMax
167 //=======================================================================
168 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
172 //=======================================================================
173 //function : NbPntsMax
175 //=======================================================================
176 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
180 //=======================================================================
183 //=======================================================================
184 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
188 //=======================================================================
191 //=======================================================================
192 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
194 Standard_Integer i, aNb;
195 TopTools_ListOfShape* pL;
197 pL=(TopTools_ListOfShape*) &myLS;
201 for (i=1; i<=aNb; ++i) {
202 const TopoDS_Shape& aS=myMSS.FindKey(i);
203 if (aS.ShapeType()==myShapeType) {
209 //=======================================================================
212 //=======================================================================
213 void GEOMAlgo_FinderShapeOn2::Perform()
225 myClsf->SetTolerance(myTolerance);
232 if (myShapeType==TopAbs_VERTEX) {
241 if (myShapeType==TopAbs_EDGE) {
250 if (myShapeType==TopAbs_FACE) {
258 //=======================================================================
259 //function : CheckData
261 //=======================================================================
262 void GEOMAlgo_FinderShapeOn2::CheckData()
264 Standard_Integer iErr;
268 if(myClsf.IsNull()) {
269 myErrorStatus=10; // myClsf=NULL
274 iErr=myClsf->ErrorStatus();
276 myErrorStatus=41; // invalid data for classifier
280 if (myShape.IsNull()) {
281 myErrorStatus=11; // myShape=NULL
285 if (!(myShapeType==TopAbs_VERTEX ||
286 myShapeType==TopAbs_EDGE ||
287 myShapeType==TopAbs_FACE ||
288 myShapeType==TopAbs_SOLID)) {
289 myErrorStatus=12; // unallowed subshape type
293 if (myState==GEOMAlgo_ST_UNKNOWN ||
294 myState==GEOMAlgo_ST_INOUT) {
295 myErrorStatus=13; // unallowed state type
299 //=======================================================================
300 //function : ProcessVertices
302 //=======================================================================
303 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
307 Standard_Boolean bIsConformState;
308 Standard_Integer i, aNb, iErr;
310 TopTools_IndexedMapOfShape aM;
313 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
315 for (i=1; i<=aNb; ++i) {
316 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
317 aP=BRep_Tool::Pnt(aV);
321 iErr=myClsf->ErrorStatus();
323 myErrorStatus=40; // point can not be classified
328 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
330 if (myShapeType==TopAbs_VERTEX){
331 if (bIsConformState) {
335 else if (bIsConformState || aSt==TopAbs_ON) {
340 //=======================================================================
341 //function : ProcessEdges
343 //=======================================================================
344 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
348 Standard_Boolean bIsConformState, bIsToBreak;
349 Standard_Integer i, aNb, iCnt, iErr;
351 TopTools_IndexedMapOfShape aM;
352 TopExp_Explorer aExp;
353 GEOMAlgo_ListIteratorOfListOfPnt aIt;
355 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
357 for (i=1; i<=aNb; ++i) {
358 GEOMAlgo_ListOfPnt aLP;
359 GEOMAlgo_StateCollector aSC;
361 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
363 aExp.Init(aE, TopAbs_VERTEX);
364 for (; aExp.More(); aExp.Next()) {
365 const TopoDS_Shape& aV=aExp.Current();
367 bIsConformState=myMSS.Contains(aV);
368 if (!bIsConformState) {
369 break;// vertex has non-conformed state
372 aSt=myMSS.FindFromKey(aV);
373 aSC.AppendState(aSt);
377 if (!bIsConformState) {
378 continue; // vertex has non-conformed state,skip edge
381 if (BRep_Tool::Degenerated(aE)) {
386 if (myState==GEOMAlgo_ST_ON) {
387 Standard_Boolean bCanBeON;
388 Standard_Real aT1, aT2;
389 Handle(Geom_Curve) aC;
391 aC=BRep_Tool::Curve(aE, aT1, aT2);
392 bCanBeON=myClsf->CanBeON(aC);
398 InnerPoints(aE, aLP);
403 bIsConformState=Standard_True;
405 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
407 if (iCnt > myNbPntsMax) {
412 const gp_Pnt& aP=aIt.Value();
416 iErr=myClsf->ErrorStatus();
418 myErrorStatus=40; // point can not be classified
424 bIsToBreak=aSC.AppendState(aSt);
432 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
433 if (myShapeType==TopAbs_EDGE) {
434 if (bIsConformState) {
438 else if (bIsConformState || aSt==TopAbs_ON) {
441 } // for (i=1; i<=aNb; ++i) next edge
443 //=======================================================================
444 //function : ProcessFaces
446 //=======================================================================
447 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
451 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
452 Standard_Integer i, aNbF, iCnt, iErr;
454 TopTools_IndexedMapOfShape aM;
455 TopExp_Explorer aExp;
456 GEOMAlgo_ListIteratorOfListOfPnt aIt;
458 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
460 for (i=1; i<=aNbF; ++i) {
461 GEOMAlgo_StateCollector aSC;
462 GEOMAlgo_ListOfPnt aLP;
464 const TopoDS_Face& aF=TopoDS::Face(aM(i));
466 if (myState==GEOMAlgo_ST_ON) {
467 Handle(Geom_Surface) aS;
469 aS=BRep_Tool::Surface(aF);
470 bCanBeON=myClsf->CanBeON(aS);
476 aExp.Init(aF, TopAbs_EDGE);
477 for (; aExp.More(); aExp.Next()) {
478 const TopoDS_Shape& aE=aExp.Current();
479 bIsConformState=myMSS.Contains(aE);
480 if (!bIsConformState) {
481 break;// edge has non-conformed state
484 aSt=myMSS.FindFromKey(aE);
485 aSC.AppendState(aSt);
489 if (!bIsConformState) {
490 continue; // edge has non-conformed state,skip face
493 InnerPoints(aF, aLP);
498 bIsConformState=Standard_True;
500 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
502 if (iCnt > myNbPntsMax) {
507 const gp_Pnt& aP=aIt.Value();
511 iErr=myClsf->ErrorStatus();
513 myErrorStatus=40; // point can not be classified
519 bIsToBreak=aSC.AppendState(aSt);
527 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
528 if (myShapeType==TopAbs_FACE) {
529 if (bIsConformState) {
533 else if (bIsConformState || aSt==TopAbs_ON) {
536 }// for (i=1; i<=aNb; ++i) next face
538 //=======================================================================
539 //function : ProcessSolids
541 //=======================================================================
542 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
546 Standard_Boolean bIsConformState;
547 Standard_Integer i, aNbS, j, aNbF;
548 TopTools_IndexedMapOfShape aM, aMF;
551 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
553 for (i=1; i<=aNbS; ++i) {
554 GEOMAlgo_StateCollector aSC;
556 const TopoDS_Shape& aSd=aM(i);
558 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
560 for (j=1; j<=aNbF; ++j) {
561 const TopoDS_Shape& aF=aMF(j);
562 bIsConformState=myMSS.Contains(aF);
563 if (!bIsConformState) {
564 break;// face has non-conformed state
567 aSt=myMSS.FindFromKey(aF);
568 aSC.AppendState(aSt);
572 if (!bIsConformState) {
573 continue; // face has non-conformed state,skip solid
578 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
579 if (bIsConformState) {
585 //=======================================================================
586 //function : InnerPoints
588 //=======================================================================
589 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
590 GEOMAlgo_ListOfPnt& aLP)
594 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
595 TopLoc_Location aLoc;
596 Handle(Poly_Triangulation) aTRF;
597 TColStd_MapOfInteger aMBN;
598 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
599 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
604 aTRF=BRep_Tool::Triangulation(aF, aLoc);
606 myErrorStatus=20; // no triangulation found
610 const gp_Trsf& aTrsf=aLoc.Transformation();
611 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
612 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
614 // map link/nbtriangles
617 for (j=j1; j<=j2; ++j) {
618 const Poly_Triangle& aTr=aTrs(j);
619 aTr.Get(n[0], n[1], n[2]);
621 for (k=0; k<3; ++k) {
622 GEOMAlgo_PassKey aPK;
624 aPK.SetIds(n[k], n[k+1]);
625 if (aMPKI.IsBound(aPK)) {
626 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
635 // boundary nodes aMBN
636 aNbLinks=aMPKI.Extent();
637 aIt.Initialize(aMPKI);
638 for (; aIt.More(); aIt.Next()) {
641 const GEOMAlgo_PassKey& aPK=aIt.Key();
645 pIds=(Standard_Integer*)aPK.Key();
646 for (k=1; k<3; ++k) {
647 aNx=*(pIds+aNbMax-k);
651 aNx=(Standard_Integer)aPK.Id(1);
653 aNx=(Standard_Integer)aPK.Id(2);
659 // inner nodes=all_nodes - boundary_nodes
662 for (j=j1; j<=j2; ++j) {
663 if (!aMBN.Contains(j)) {
664 aP=aNodes(j).Transformed(aTrsf);
671 if (!aNb && myNbPntsMin) {
672 // try to fill it yourself
673 Standard_Boolean bIsDone;
674 Standard_Integer aN1, aN2;
675 Handle(Geom_Surface) aS;
676 GeomAdaptor_Surface aGAS;
677 GeomAbs_SurfaceType aType;
679 aS=BRep_Tool::Surface(aF);
681 aType=aGAS.GetType();
682 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
684 aNbLinks=aMPKI.Extent();
685 aIt.Initialize(aMPKI);
686 for (; aIt.More(); aIt.Next()) {
689 // take the first having occured inner link
691 const GEOMAlgo_PassKey& aPK=aIt.Key();
695 pIds=(Standard_Integer*)aPK.Key();
696 aN1=*(pIds+aNbMax-1);
697 aN2=*(pIds+aNbMax-2);
700 aN1=(Standard_Integer)aPK.Id(1);
701 aN2=(Standard_Integer)aPK.Id(2);
703 aP1=aNodes(aN1).Transformed(aTrsf);
704 aP2=aNodes(aN2).Transformed(aTrsf);
706 if (aType==GeomAbs_Cylinder) {
707 Standard_Real aTolSM;
710 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
711 aCyl=aGAS.Cylinder();
712 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
717 BRepLib_MakeEdge aBME(aP1, aP2);
718 bIsDone=aBME.IsDone();
720 myErrorStatus=30; //can not obtain the line fron the link
724 const TopoDS_Shape& aSx=aBME.Shape();
725 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
727 InnerPoints(aE, myNbPntsMin, aLP);
730 }// for (; aIt.More(); aIt.Next())
731 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
732 }// if (!aNb && myNbPntsMin) {
734 //=======================================================================
735 //function : InnerPoints
737 //=======================================================================
738 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
739 GEOMAlgo_ListOfPnt& aLP)
743 Standard_Integer j, aNbNodes, aIndex, aNb;
744 Handle(Poly_PolygonOnTriangulation) aPTE;
745 Handle(Poly_Triangulation) aTRE;
746 TopLoc_Location aLoc;
750 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
751 if (aTRE.IsNull() || aPTE.IsNull()) {
752 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
754 myErrorStatus=20; // no triangulation found
757 const gp_Trsf& aTrsf=aLoc.Transformation();
758 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
760 aNbNodes=aPE->NbNodes();
761 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
762 for (j=low+1; j<up; ++j) {
763 aP=aNodes(j).Transformed(aTrsf);
768 const gp_Trsf& aTrsf=aLoc.Transformation();
769 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
771 aNbNodes=aPTE->NbNodes();
772 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
773 for (j=2; j<aNbNodes; ++j) {
775 aP=aNodes(aIndex).Transformed(aTrsf);
781 if (!aNb && myNbPntsMin) {
782 // try to fill it yourself
783 InnerPoints(aE, myNbPntsMin, aLP);
787 //=======================================================================
788 //function : InnerPoints
790 //=======================================================================
791 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
792 const Standard_Integer aNbPntsMin,
793 GEOMAlgo_ListOfPnt& aLP)
795 // try to fill it yourself
796 Standard_Boolean bInf1, bInf2;
797 Standard_Integer j, aNbT;
798 Standard_Real dT, aT, aT1, aT2;
800 Handle(Geom_Curve) aC3D;
802 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
807 bInf1=Precision::IsNegativeInfinite(aT1);
808 bInf2=Precision::IsPositiveInfinite(aT2);
809 if (bInf1 || bInf2) {
815 for (j=1; j<=aNbPntsMin; ++j) {
827 // 12 -unallowed type of subshapes
828 // 13 -unallowed state
829 // 15 -unallowed surface type
830 // 20- no triangulation found
831 // 30- can not obtain the line from the link
832 // 40- point can not be classified
833 // 41- invalid data for classifier