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_FinderShapeOn2.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_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
90 myShapeType=TopAbs_VERTEX;
91 myState=GEOMAlgo_ST_UNKNOWN;
95 //=======================================================================
98 //=======================================================================
99 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
102 //=======================================================================
105 //=======================================================================
106 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
110 //=======================================================================
113 //=======================================================================
114 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
118 //=======================================================================
119 //function : SetShapeType
121 //=======================================================================
122 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
126 //=======================================================================
127 //function : ShapeType
129 //=======================================================================
130 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
134 //=======================================================================
135 //function : SetState
137 //=======================================================================
138 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
142 //=======================================================================
145 //=======================================================================
146 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
150 //=======================================================================
151 //function : SetNbPntsMin
153 //=======================================================================
154 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
158 //=======================================================================
159 //function : NbPntsMin
161 //=======================================================================
162 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
166 //=======================================================================
167 //function : SetNbPntsMax
169 //=======================================================================
170 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
174 //=======================================================================
175 //function : NbPntsMax
177 //=======================================================================
178 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
182 //=======================================================================
185 //=======================================================================
186 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
190 //=======================================================================
193 //=======================================================================
194 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::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_FinderShapeOn2::Perform()
227 myClsf->SetTolerance(myTolerance);
234 if (myShapeType==TopAbs_VERTEX) {
243 if (myShapeType==TopAbs_EDGE) {
252 if (myShapeType==TopAbs_FACE) {
260 //=======================================================================
261 //function : CheckData
263 //=======================================================================
264 void GEOMAlgo_FinderShapeOn2::CheckData()
266 Standard_Integer iErr;
270 if(myClsf.IsNull()) {
271 myErrorStatus=10; // myClsf=NULL
276 iErr=myClsf->ErrorStatus();
278 myErrorStatus=41; // invalid data for classifier
282 if (myShape.IsNull()) {
283 myErrorStatus=11; // myShape=NULL
287 if (!(myShapeType==TopAbs_VERTEX ||
288 myShapeType==TopAbs_EDGE ||
289 myShapeType==TopAbs_FACE ||
290 myShapeType==TopAbs_SOLID)) {
291 myErrorStatus=12; // unallowed subshape type
295 if (myState==GEOMAlgo_ST_UNKNOWN ||
296 myState==GEOMAlgo_ST_INOUT) {
297 myErrorStatus=13; // unallowed state type
301 //=======================================================================
302 //function : ProcessVertices
304 //=======================================================================
305 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
309 Standard_Boolean bIsConformState;
310 Standard_Integer i, aNb, iErr;
312 TopTools_IndexedMapOfShape aM;
315 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
317 for (i=1; i<=aNb; ++i) {
318 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
319 aP=BRep_Tool::Pnt(aV);
323 iErr=myClsf->ErrorStatus();
325 myErrorStatus=40; // point can not be classified
330 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
332 if (myShapeType==TopAbs_VERTEX){
333 if (bIsConformState) {
337 else if (bIsConformState || aSt==TopAbs_ON) {
342 //=======================================================================
343 //function : ProcessEdges
345 //=======================================================================
346 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
350 Standard_Boolean bIsConformState, bIsToBreak;
351 Standard_Integer i, aNb, iCnt, iErr;
353 TopTools_IndexedMapOfShape aM;
354 TopExp_Explorer aExp;
355 GEOMAlgo_ListIteratorOfListOfPnt aIt;
357 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
359 for (i=1; i<=aNb; ++i) {
360 GEOMAlgo_ListOfPnt aLP;
361 GEOMAlgo_StateCollector aSC;
363 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
365 aExp.Init(aE, TopAbs_VERTEX);
366 for (; aExp.More(); aExp.Next()) {
367 const TopoDS_Shape& aV=aExp.Current();
369 bIsConformState=myMSS.Contains(aV);
370 if (!bIsConformState) {
371 break;// vertex has non-conformed state
374 aSt=myMSS.FindFromKey(aV);
375 aSC.AppendState(aSt);
379 if (!bIsConformState) {
380 continue; // vertex has non-conformed state,skip edge
383 if (BRep_Tool::Degenerated(aE)) {
388 if (myState==GEOMAlgo_ST_ON) {
389 Standard_Boolean bCanBeON;
390 Standard_Real aT1, aT2;
391 Handle(Geom_Curve) aC;
393 aC=BRep_Tool::Curve(aE, aT1, aT2);
394 bCanBeON=myClsf->CanBeON(aC);
400 InnerPoints(aE, aLP);
405 bIsConformState=Standard_True;
407 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
409 if (iCnt > myNbPntsMax) {
414 const gp_Pnt& aP=aIt.Value();
418 iErr=myClsf->ErrorStatus();
420 myErrorStatus=40; // point can not be classified
426 bIsToBreak=aSC.AppendState(aSt);
434 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
435 if (myShapeType==TopAbs_EDGE) {
436 if (bIsConformState) {
440 else if (bIsConformState || aSt==TopAbs_ON) {
443 } // for (i=1; i<=aNb; ++i) next edge
445 //=======================================================================
446 //function : ProcessFaces
448 //=======================================================================
449 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
453 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
454 Standard_Integer i, aNbF, iCnt, iErr;
456 TopTools_IndexedMapOfShape aM;
457 TopExp_Explorer aExp;
458 GEOMAlgo_ListIteratorOfListOfPnt aIt;
460 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
462 for (i=1; i<=aNbF; ++i) {
463 GEOMAlgo_StateCollector aSC;
464 GEOMAlgo_ListOfPnt aLP;
466 const TopoDS_Face& aF=TopoDS::Face(aM(i));
468 if (myState==GEOMAlgo_ST_ON) {
469 Handle(Geom_Surface) aS;
471 aS=BRep_Tool::Surface(aF);
472 bCanBeON=myClsf->CanBeON(aS);
478 aExp.Init(aF, TopAbs_EDGE);
479 for (; aExp.More(); aExp.Next()) {
480 const TopoDS_Shape& aE=aExp.Current();
481 bIsConformState=myMSS.Contains(aE);
482 if (!bIsConformState) {
483 break;// edge has non-conformed state
486 aSt=myMSS.FindFromKey(aE);
487 aSC.AppendState(aSt);
491 if (!bIsConformState) {
492 continue; // edge has non-conformed state,skip face
495 InnerPoints(aF, aLP);
500 bIsConformState=Standard_True;
502 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
504 if (iCnt > myNbPntsMax) {
509 const gp_Pnt& aP=aIt.Value();
513 iErr=myClsf->ErrorStatus();
515 myErrorStatus=40; // point can not be classified
521 bIsToBreak=aSC.AppendState(aSt);
529 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
530 if (myShapeType==TopAbs_FACE) {
531 if (bIsConformState) {
535 else if (bIsConformState || aSt==TopAbs_ON) {
538 }// for (i=1; i<=aNb; ++i) next face
540 //=======================================================================
541 //function : ProcessSolids
543 //=======================================================================
544 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
548 Standard_Boolean bIsConformState;
549 Standard_Integer i, aNbS, j, aNbF;
550 TopTools_IndexedMapOfShape aM, aMF;
553 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
555 for (i=1; i<=aNbS; ++i) {
556 GEOMAlgo_StateCollector aSC;
558 const TopoDS_Shape& aSd=aM(i);
560 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
562 for (j=1; j<=aNbF; ++j) {
563 const TopoDS_Shape& aF=aMF(j);
564 bIsConformState=myMSS.Contains(aF);
565 if (!bIsConformState) {
566 break;// face has non-conformed state
569 aSt=myMSS.FindFromKey(aF);
570 aSC.AppendState(aSt);
574 if (!bIsConformState) {
575 continue; // face has non-conformed state,skip solid
580 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
581 if (bIsConformState) {
587 //=======================================================================
588 //function : InnerPoints
590 //=======================================================================
591 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
592 GEOMAlgo_ListOfPnt& aLP)
596 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
597 TopLoc_Location aLoc;
598 Handle(Poly_Triangulation) aTRF;
599 TColStd_MapOfInteger aMBN;
600 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
601 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
606 aTRF=BRep_Tool::Triangulation(aF, aLoc);
608 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
609 myWarningStatus=20; // no triangulation found
612 aTRF=BRep_Tool::Triangulation(aF, aLoc);
615 const gp_Trsf& aTrsf=aLoc.Transformation();
616 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
617 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
619 // map link/nbtriangles
622 for (j=j1; j<=j2; ++j) {
623 const Poly_Triangle& aTr=aTrs(j);
624 aTr.Get(n[0], n[1], n[2]);
626 for (k=0; k<3; ++k) {
627 GEOMAlgo_PassKey aPK;
629 aPK.SetIds(n[k], n[k+1]);
630 if (aMPKI.IsBound(aPK)) {
631 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
640 // boundary nodes aMBN
641 aNbLinks=aMPKI.Extent();
642 aIt.Initialize(aMPKI);
643 for (; aIt.More(); aIt.Next()) {
646 const GEOMAlgo_PassKey& aPK=aIt.Key();
650 pIds=(Standard_Integer*)aPK.Key();
651 for (k=1; k<3; ++k) {
652 aNx=*(pIds+aNbMax-k);
656 aNx=(Standard_Integer)aPK.Id(1);
658 aNx=(Standard_Integer)aPK.Id(2);
664 // inner nodes=all_nodes - boundary_nodes
667 for (j=j1; j<=j2; ++j) {
668 if (!aMBN.Contains(j)) {
669 aP=aNodes(j).Transformed(aTrsf);
676 if (!aNb && myNbPntsMin) {
677 // try to fill it yourself
678 Standard_Boolean bIsDone;
679 Standard_Integer aN1, aN2;
680 Handle(Geom_Surface) aS;
681 GeomAdaptor_Surface aGAS;
682 GeomAbs_SurfaceType aType;
684 aS=BRep_Tool::Surface(aF);
686 aType=aGAS.GetType();
687 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
689 aNbLinks=aMPKI.Extent();
690 aIt.Initialize(aMPKI);
691 for (; aIt.More(); aIt.Next()) {
694 // take the first having occured inner link
696 const GEOMAlgo_PassKey& aPK=aIt.Key();
700 pIds=(Standard_Integer*)aPK.Key();
701 aN1=*(pIds+aNbMax-1);
702 aN2=*(pIds+aNbMax-2);
705 aN1=(Standard_Integer)aPK.Id(1);
706 aN2=(Standard_Integer)aPK.Id(2);
708 aP1=aNodes(aN1).Transformed(aTrsf);
709 aP2=aNodes(aN2).Transformed(aTrsf);
711 if (aType==GeomAbs_Cylinder) {
712 Standard_Real aTolSM;
715 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
716 aCyl=aGAS.Cylinder();
717 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
722 BRepLib_MakeEdge aBME(aP1, aP2);
723 bIsDone=aBME.IsDone();
725 myErrorStatus=30; //can not obtain the line fron the link
729 const TopoDS_Shape& aSx=aBME.Shape();
730 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
732 InnerPoints(aE, myNbPntsMin, aLP);
735 }// for (; aIt.More(); aIt.Next())
736 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
737 }// if (!aNb && myNbPntsMin) {
739 //=======================================================================
740 //function : InnerPoints
742 //=======================================================================
743 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
744 GEOMAlgo_ListOfPnt& aLP)
748 Standard_Integer j, aNbNodes, aIndex, aNb;
749 Handle(Poly_PolygonOnTriangulation) aPTE;
750 Handle(Poly_Triangulation) aTRE;
751 TopLoc_Location aLoc;
755 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
756 if (aTRE.IsNull() || aPTE.IsNull()) {
757 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
759 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
760 myErrorStatus=20; // no triangulation found
763 aPE = BRep_Tool::Polygon3D(aE, aLoc);
765 const gp_Trsf& aTrsf=aLoc.Transformation();
766 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
768 aNbNodes=aPE->NbNodes();
769 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
770 for (j=low+1; j<up; ++j) {
771 aP=aNodes(j).Transformed(aTrsf);
776 const gp_Trsf& aTrsf=aLoc.Transformation();
777 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
779 aNbNodes=aPTE->NbNodes();
780 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
781 for (j=2; j<aNbNodes; ++j) {
783 aP=aNodes(aIndex).Transformed(aTrsf);
789 if (!aNb && myNbPntsMin) {
790 // try to fill it yourself
791 InnerPoints(aE, myNbPntsMin, aLP);
795 //=======================================================================
796 //function : InnerPoints
798 //=======================================================================
799 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
800 const Standard_Integer aNbPntsMin,
801 GEOMAlgo_ListOfPnt& aLP)
803 // try to fill it yourself
804 Standard_Boolean bInf1, bInf2;
805 Standard_Integer j, aNbT;
806 Standard_Real dT, aT, aT1, aT2;
808 Handle(Geom_Curve) aC3D;
810 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
815 bInf1=Precision::IsNegativeInfinite(aT1);
816 bInf2=Precision::IsPositiveInfinite(aT2);
817 if (bInf1 || bInf2) {
823 for (j=1; j<=aNbPntsMin; ++j) {
835 // 12 -unallowed type of subshapes
836 // 13 -unallowed state
837 // 15 -unallowed surface type
838 // 20- no triangulation found
839 // 30- can not obtain the line from the link
840 // 40- point can not be classified
841 // 41- invalid data for classifier