1 // Copyright (C) 2007-2024 CEA, EDF, 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, or (at your option) any later version.
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
23 // File: GEOMAlgo_FinderShapeOn2.cxx
24 // Created: Fri Mar 4 10:31:06 2005
25 // Author: Peter KURNEV
28 #include <GEOMAlgo_FinderShapeOn2.hxx>
29 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
30 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
31 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
32 #include <GEOMAlgo_PassKey.hxx>
33 #include <GEOMAlgo_StateCollector.hxx>
34 #include <GEOMAlgo_SurfaceTools.hxx>
36 #include <GEOMUtils.hxx>
38 #include <Bnd_Box.hxx>
39 #include <BRep_Tool.hxx>
40 #include <BRepBndLib.hxx>
41 #include <BRepMesh_IncrementalMesh.hxx>
42 #include <BRepTools.hxx>
43 #include <Geom_Curve.hxx>
44 #include <Geom_Surface.hxx>
45 #include <Geom2d_Line.hxx>
46 #include <Geom2dAdaptor_Curve.hxx>
47 #include <Geom2dHatch_Hatcher.hxx>
48 #include <gp_Dir2d.hxx>
49 #include <gp_Pnt2d.hxx>
51 #include <gp_Trsf.hxx>
52 #include <HatchGen_Domain.hxx>
53 #include <IntTools_Tools.hxx>
54 #include <Poly_Array1OfTriangle.hxx>
55 #include <Poly_Polygon3D.hxx>
56 #include <Poly_PolygonOnTriangulation.hxx>
57 #include <Poly_Triangle.hxx>
58 #include <Poly_Triangulation.hxx>
59 #include <Precision.hxx>
60 #include <TColgp_Array1OfPnt.hxx>
61 #include <TColStd_Array1OfInteger.hxx>
62 #include <TColStd_MapOfInteger.hxx>
63 #include <TopAbs_State.hxx>
65 #include <TopExp_Explorer.hxx>
66 #include <TopLoc_Location.hxx>
68 #include <TopoDS_Edge.hxx>
69 #include <TopoDS_Face.hxx>
70 #include <TopoDS_Shape.hxx>
71 #include <TopoDS_Vertex.hxx>
72 #include <TopTools_IndexedMapOfShape.hxx>
73 #include <IntTools_Context.hxx>
75 //=======================================================================
78 //=======================================================================
79 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
84 myShapeType=TopAbs_VERTEX;
85 myState=GEOMAlgo_ST_UNKNOWN;
89 //=======================================================================
92 //=======================================================================
93 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
96 //=======================================================================
99 //=======================================================================
100 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
104 //=======================================================================
107 //=======================================================================
108 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
112 //=======================================================================
113 //function : SetShapeType
115 //=======================================================================
116 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
120 //=======================================================================
121 //function : ShapeType
123 //=======================================================================
124 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
128 //=======================================================================
129 //function : SetState
131 //=======================================================================
132 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
136 //=======================================================================
139 //=======================================================================
140 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
144 //=======================================================================
145 //function : SetNbPntsMin
147 //=======================================================================
148 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
152 //=======================================================================
153 //function : NbPntsMin
155 //=======================================================================
156 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
160 //=======================================================================
161 //function : SetNbPntsMax
163 //=======================================================================
164 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
168 //=======================================================================
169 //function : NbPntsMax
171 //=======================================================================
172 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
176 //=======================================================================
179 //=======================================================================
180 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
184 //=======================================================================
187 //=======================================================================
188 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
190 Standard_Integer i, aNb;
191 TopTools_ListOfShape* pL;
193 pL=(TopTools_ListOfShape*) &myLS;
197 for (i=1; i<=aNb; ++i) {
198 const TopoDS_Shape& aS=myMSS.FindKey(i);
199 if (aS.ShapeType()==myShapeType) {
205 //=======================================================================
208 //=======================================================================
209 void GEOMAlgo_FinderShapeOn2::Perform()
221 // Initialize the context
222 GEOMAlgo_ShapeAlgo::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 sub-shape 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;
349 TopAbs_State aSt = TopAbs_UNKNOWN; // todo: aSt must be explicitly initilized to avoid warning (see below)
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 bIsConformState=Standard_False;
364 aExp.Init(aE, TopAbs_VERTEX);
365 for (; aExp.More(); aExp.Next()) {
366 const TopoDS_Shape& aV=aExp.Current();
368 bIsConformState=myMSS.Contains(aV);
369 if (!bIsConformState) {
370 break;// vertex has non-conformed state
373 aSt=myMSS.FindFromKey(aV);
374 aSC.AppendState(aSt);
378 if (!bIsConformState) {
379 continue; // vertex has non-conformed state,skip edge
382 if (BRep_Tool::Degenerated(aE)) {
383 myMSS.Add(aE, aSt); // todo: aSt must be explicitly initilized to avoid warning (see above)
387 if (myState==GEOMAlgo_ST_ON) {
388 Standard_Boolean bCanBeON;
389 Standard_Real aT1, aT2;
390 Handle(Geom_Curve) aC;
392 aC=BRep_Tool::Curve(aE, aT1, aT2);
393 bCanBeON=myClsf->CanBeON(aC);
399 InnerPoints(aE, aLP);
404 bIsConformState=Standard_True;
406 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
408 if (iCnt > myNbPntsMax) {
413 const gp_Pnt& aP=aIt.Value();
417 iErr=myClsf->ErrorStatus();
419 myErrorStatus=40; // point can not be classified
425 bIsToBreak=aSC.AppendState(aSt);
433 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
434 if (myShapeType==TopAbs_EDGE) {
435 if (bIsConformState) {
439 else if (bIsConformState || aSt==TopAbs_ON) {
442 } // for (i=1; i<=aNb; ++i) next edge
444 //=======================================================================
445 //function : ProcessFaces
447 //=======================================================================
448 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
452 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
453 Standard_Integer i, aNbF, iCnt, iErr;
455 TopTools_IndexedMapOfShape aM;
456 TopExp_Explorer aExp;
457 GEOMAlgo_ListIteratorOfListOfPnt aIt;
459 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
461 for (i=1; i<=aNbF; ++i) {
462 GEOMAlgo_StateCollector aSC;
463 GEOMAlgo_ListOfPnt aLP;
465 const TopoDS_Face& aF=TopoDS::Face(aM(i));
467 if (myState==GEOMAlgo_ST_ON) {
468 Handle(Geom_Surface) aS;
470 aS=BRep_Tool::Surface(aF);
471 bCanBeON=myClsf->CanBeON(aS);
478 bIsConformState=Standard_False;
480 aExp.Init(aF, TopAbs_EDGE);
481 for (; aExp.More(); aExp.Next()) {
482 const TopoDS_Shape& aE=aExp.Current();
483 bIsConformState=myMSS.Contains(aE);
484 if (!bIsConformState) {
485 break;// edge has non-conformed state
488 aSt=myMSS.FindFromKey(aE);
489 aSC.AppendState(aSt);
493 if (!bIsConformState) {
494 continue; // edge has non-conformed state,skip face
497 InnerPoints(aF, aLP);
502 bIsConformState=Standard_True;
504 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
506 if (iCnt > myNbPntsMax) {
511 const gp_Pnt& aP=aIt.Value();
515 iErr=myClsf->ErrorStatus();
517 myErrorStatus=40; // point can not be classified
523 bIsToBreak=aSC.AppendState(aSt);
531 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
532 if (myShapeType==TopAbs_FACE) {
533 if (bIsConformState) {
537 else if (bIsConformState || aSt==TopAbs_ON) {
540 }// for (i=1; i<=aNb; ++i) next face
542 //=======================================================================
543 //function : ProcessSolids
545 //=======================================================================
546 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
550 Standard_Boolean bIsConformState;
551 Standard_Integer i, aNbS, j, aNbF;
552 TopTools_IndexedMapOfShape aM, aMF;
555 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
557 for (i=1; i<=aNbS; ++i) {
558 GEOMAlgo_StateCollector aSC;
560 const TopoDS_Shape& aSd=aM(i);
562 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
564 bIsConformState=Standard_False;
567 for (j=1; j<=aNbF; ++j) {
568 const TopoDS_Shape& aF=aMF(j);
569 bIsConformState=myMSS.Contains(aF);
570 if (!bIsConformState) {
571 break;// face has non-conformed state
574 aSt=myMSS.FindFromKey(aF);
575 aSC.AppendState(aSt);
579 if (!bIsConformState) {
580 continue; // face has non-conformed state,skip solid
585 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
586 if (bIsConformState) {
592 //=======================================================================
593 //function : InnerPoints
595 //=======================================================================
596 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
597 GEOMAlgo_ListOfPnt& aLP)
599 Standard_Integer j, j1, j2, k, n[4], aNx, aNb, iCnt;//, aNbLinks, aNbMax, *pIds;
600 TopLoc_Location aLoc;
601 Handle(Poly_Triangulation) aTRF;
602 TColStd_MapOfInteger aMBN;
603 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
604 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
611 if (!GEOMUtils::MeshShape(aF, /*deflection*/0.001, /*forced*/false,
612 /*angle deflection*/0.349066, /*isRelative*/true,
613 /*doPostCheck*/true)) {
614 myWarningStatus=20; // no triangulation found
617 aTRF=BRep_Tool::Triangulation(aF, aLoc);
619 const gp_Trsf& aTrsf=aLoc.Transformation();
621 // map link/nbtriangles
623 j2 = aTRF->NbTriangles();
624 for (j=j1; j<=j2; ++j) {
625 const Poly_Triangle& aTr = aTRF->Triangle(j);
626 aTr.Get(n[0], n[1], n[2]);
628 for (k=0; k<3; ++k) {
629 GEOMAlgo_PassKey aPK;
631 aPK.SetIds(n[k], n[k+1]);
632 if (aMPKI.IsBound(aPK)) {
633 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
642 // boundary nodes aMBN
643 aIt.Initialize(aMPKI);
644 for (; aIt.More(); aIt.Next()) {
647 const GEOMAlgo_PassKey& aPK=aIt.Key();
648 aNx=(Standard_Integer)aPK.Id(1);
650 aNx=(Standard_Integer)aPK.Id(2);
656 // inner nodes=all_nodes - boundary_nodes
659 for (j=j1; j<=j2; ++j) {
660 if (!aMBN.Contains(j)) {
661 aP=aTRF->Node(j).Transformed(aTrsf);
668 //modified by NIZNHY-PKV Mon Sep 24 08:42:32 2012f
669 if (!aNb && myNbPntsMin) { // A
670 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
671 Standard_Integer i, aNb, aIx, /*iErr, */aNbDomains;
672 Standard_Real aUMin, aUMax, aVMin, aVMax, dU, aUx, aVx, aV1, aV2;
674 gp_Dir2d aD2D (0., 1.);
676 Handle(Geom2d_Line) aL2D;
677 Handle(Geom_Surface) aS;
681 aFF.Orientation (TopAbs_FORWARD);
683 Geom2dHatch_Hatcher& aHatcher=myContext->Hatcher(aFF);
685 aS=BRep_Tool::Surface(aFF);
686 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
689 dU=(aUMax-aUMin)/aNb;
690 for (i=1; i<aNb; ++i) {
692 aP2D.SetCoord(aUx, 0.);
693 aL2D=new Geom2d_Line (aP2D, aD2D);
694 Geom2dAdaptor_Curve aHCur(aL2D);
696 aHatcher.ClrHatchings();
697 aIx=aHatcher.AddHatching(aHCur);
700 bIsDone=aHatcher.TrimDone(aIx);
706 aHatcher.ComputeDomains(aIx);
707 bIsDone=aHatcher.IsDone(aIx);
712 aNbDomains=aHatcher.NbDomains(aIx);
713 for (j=1; j<=aNbDomains; ++j) {
714 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, j) ;
716 bHasFirstPoint=aDomain.HasFirstPoint();
717 bHasSecondPoint=aDomain.HasSecondPoint();
718 if (!bHasFirstPoint || !bHasSecondPoint) {
722 aV1=aDomain.FirstPoint().Parameter();
723 aV2=aDomain.SecondPoint().Parameter();
724 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
726 aS->D0(aUx, aVx, aPx);
730 }// for (i=1; i<aNb; ++i) {
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 if (!GEOMUtils::MeshShape(aE, /*deflection*/0.001, /*forced*/false,
750 /*angle deflection*/0.349066, /*isRelative*/true,
751 /*doPostCheck*/true)) {
752 myErrorStatus=20; // no triangulation found
755 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
756 if (aTRE.IsNull() || aPTE.IsNull()) {
757 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
758 const gp_Trsf& aTrsf=aLoc.Transformation();
759 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
761 aNbNodes=aPE->NbNodes();
762 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
763 for (j=low+1; j<up; ++j) {
764 aP=aNodes(j).Transformed(aTrsf);
769 const gp_Trsf& aTrsf=aLoc.Transformation();
771 aNbNodes=aPTE->NbNodes();
772 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
773 for (j=2; j<aNbNodes; ++j) {
775 aP=aTRE->Node(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 sub-shapes
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
834 // 42- can not compute hatching