1 // Created on: 1994-10-10
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Tool.hxx>
19 #include <Geom_Circle.hxx>
20 #include <GeomProjLib.hxx>
22 #include <Precision.hxx>
23 #include <Standard_ProgramError.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopOpeBRep.hxx>
27 #include <TopOpeBRep_FacesFiller.hxx>
28 #include <TopOpeBRep_FacesIntersector.hxx>
29 #include <TopOpeBRep_FFDumper.hxx>
30 #include <TopOpeBRep_LineInter.hxx>
31 #include <TopOpeBRep_PointClassifier.hxx>
32 #include <TopOpeBRep_VPointInter.hxx>
33 #include <TopOpeBRep_VPointInterClassifier.hxx>
34 #include <TopOpeBRep_VPointInterIterator.hxx>
35 #include <TopOpeBRepDS_HDataStructure.hxx>
36 #include <TopOpeBRepDS_Transition.hxx>
37 #include <TopOpeBRepTool_2d.hxx>
38 #include <TopOpeBRepTool_EXPORT.hxx>
39 #include <TopOpeBRepTool_SC.hxx>
41 //#include <BRepAdaptor_Curve2d.hxx>
42 Standard_EXPORT Standard_Boolean FUN_projPonL(const gp_Pnt& P,const TopOpeBRep_LineInter& L,const TopOpeBRep_FacesFiller& FF,
43 Standard_Real& paramL)
45 Standard_Boolean paramLdef = Standard_False;
46 Standard_Integer Esi = (L.ArcIsEdge(1)) ? 1:2;
47 const TopoDS_Edge& E = TopoDS::Edge(L.Arc());
48 Standard_Boolean hasC3D = FC2D_HasC3D(E);
51 BRepAdaptor_Curve BAC(E);
52 paramLdef = FUN_tool_projPonC(P,BAC,paramL,dist);
55 BRepAdaptor_Curve2d BAC2D;
56 if (Esi == 1) BAC2D.Initialize(E,FF.Face(1));
57 else if (Esi == 2) BAC2D.Initialize(E,FF.Face(2));
58 paramLdef = FUN_tool_projPonC2D(P,BAC2D,paramL,dist);
64 void debffsamdom(void){}
67 static void FUN_MakeERL(TopOpeBRep_FacesIntersector& FI,TopTools_ListOfShape& ERL)
70 const TopTools_IndexedMapOfShape& mer = FI.Restrictions();
71 for ( Standard_Integer ie = 1, ne = mer.Extent(); ie <= ne; ie++) {
72 const TopoDS_Edge& E = TopoDS::Edge(mer.FindKey(ie));
77 //=======================================================================
78 //function : TopOpeBRep_FacesFiller
80 //=======================================================================
81 TopOpeBRep_FacesFiller::TopOpeBRep_FacesFiller() : myPShapeClassifier(NULL)
85 myHFFD = new TopOpeBRep_FFDumper(this);
89 //=======================================================================
90 //function : PShapeClassifier
92 //=======================================================================
93 TopOpeBRepTool_PShapeClassifier TopOpeBRep_FacesFiller::PShapeClassifier() const
95 return myPShapeClassifier;
98 //=======================================================================
99 //function : SetPShapeClassifier
101 //=======================================================================
102 void TopOpeBRep_FacesFiller::SetPShapeClassifier(const TopOpeBRepTool_PShapeClassifier& PSC)
104 myPShapeClassifier = PSC;
107 //=======================================================================
110 //=======================================================================
111 void TopOpeBRep_FacesFiller::Insert(const TopoDS_Shape& S1,const TopoDS_Shape& S2,TopOpeBRep_FacesIntersector& FACINT,const Handle(TopOpeBRepDS_HDataStructure)& HDS)
113 myF1 = TopoDS::Face(S1); myF1ori = S1.Orientation();
114 myF2 = TopoDS::Face(S2); myF2ori = S2.Orientation();
115 myFacesIntersector = &FACINT;
117 myDS = &(HDS->ChangeDS());
118 if (myPShapeClassifier == NULL) myPShapeClassifier = new TopOpeBRepTool_ShapeClassifier();
121 Standard_Integer exF1,exF2; GetTraceIndex(exF1,exF2);
122 myFacesIntersector->InitLine();
123 for (; myFacesIntersector->MoreLine(); myFacesIntersector->NextLine()) myFacesIntersector->CurrentLine().SetTraceIndex(exF1,exF2);
127 Standard_Boolean samdom = myFacesIntersector->SameDomain();
129 myDS->FillShapesSameDomain(S1,S2);
133 myFacesIntersector->InitLine();
134 for (; myFacesIntersector->MoreLine(); myFacesIntersector->NextLine()) {
135 TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine();
136 L.SetFaces(TopoDS::Face(S1),TopoDS::Face(S2));
141 myFacesIntersector->InitLine();
142 for (; myFacesIntersector->MoreLine(); myFacesIntersector->NextLine()) {
143 TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine();
149 ProcessSectionEdges();
150 myFFfirstDSP = myDS->NbPoints() + 1;
152 FUN_MakeERL((*myFacesIntersector), myERL); // BUG
154 myFacesIntersector->InitLine();
155 for (; myFacesIntersector->MoreLine(); myFacesIntersector->NextLine()) {
156 TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine();
163 //=======================================================================
164 //function : ChangePointClassifier
166 //=======================================================================
167 TopOpeBRep_PointClassifier& TopOpeBRep_FacesFiller::ChangePointClassifier()
169 return myPointClassifier;
173 //=======================================================================
174 //function : LoadLine
176 //=======================================================================
177 void TopOpeBRep_FacesFiller::LoadLine(TopOpeBRep_LineInter& L)
180 Standard_Boolean bchk = CheckLine(L);
181 Standard_Boolean binl = L.INL();
184 TopOpeBRep_TypeLineCurve t = L.TypeLineCurve();
185 if ( !bchk && binl && t == TopOpeBRep_LINE ) {
186 bchk = Standard_True;
191 if (!myLineOK) return;
193 L.ComputeFaceFaceTransition();
196 //=======================================================================
197 //function : CheckLine
199 // returns False if L is WALKING line with a number of VPoints < 2
201 //=======================================================================
202 Standard_Boolean TopOpeBRep_FacesFiller::CheckLine(TopOpeBRep_LineInter& L) const
204 Standard_Real tol1,tol2;
205 myFacesIntersector->GetTolerances(tol1,tol2);
207 Standard_Boolean check = Standard_True;
208 TopOpeBRep_TypeLineCurve t = L.TypeLineCurve();
209 Standard_Integer nbvp = L.NbVPoint();
211 if ( t == TopOpeBRep_WALKING ) {
214 std::cout<<"\n=== Nb de IntPatch_Point sur WL incorrect : "<<nbvp<<" ===\n";
216 check = Standard_False;
219 else if (t == TopOpeBRep_LINE) {
220 Standard_Integer np = 0;
221 TopOpeBRep_VPointInterIterator VPI;
223 for ( VPI.Init(L); VPI.More(); VPI.Next()) {
224 const TopOpeBRep_VPointInter& VP = VPI.CurrentVP();
225 if ( VP.Keep() ) np++;
228 return Standard_True;
231 TopOpeBRep_VPointInter A,B;
233 for ( VPI.Init(L); VPI.More(); VPI.Next()) {
234 const TopOpeBRep_VPointInter& VP = VPI.CurrentVP();
235 if ( !VP.Keep() ) continue;
237 if ( np == 1 ) A = VP;
238 if ( np == 2 ) B = VP;
241 Standard_Boolean isAV1 = A.IsVertexOnS1();
242 Standard_Boolean isAV2 = A.IsVertexOnS2();
244 if (isAV1) V1 = A.VertexOnS1();
245 if (isAV2) V1 = A.VertexOnS2();
246 Standard_Boolean isBV1 = B.IsVertexOnS1();
247 Standard_Boolean isBV2 = B.IsVertexOnS2();
249 if (isBV1) V2 = B.VertexOnS1();
250 if (isBV2) V2 = B.VertexOnS2();
252 if ( !V1.IsNull() && ( V1.IsSame(V2) ) ) {
253 return Standard_False;
257 Standard_Boolean notrnotw = (t != TopOpeBRep_RESTRICTION && t != TopOpeBRep_WALKING);
259 if (t == TopOpeBRep_CIRCLE) {
260 // cto 012 D2, faces 6 et 1, line 3 incorrecte.
262 Standard_Integer iINON1,iINONn,nINON;
263 myLine->VPBounds(iINON1,iINONn,nINON);
266 const TopOpeBRep_VPointInter& A = myLine->VPoint(iINON1);
267 const TopOpeBRep_VPointInter& B = myLine->VPoint(iINONn);
268 Standard_Real parA = A.ParameterOnLine();
269 Standard_Real parB = B.ParameterOnLine();
270 Standard_Boolean conf = (fabs(parA-parB) < tol1);
272 check = Standard_False;
276 else if (t == TopOpeBRep_HYPERBOLA) {
277 Standard_Integer iINON1,iINONn,nINON;
278 myLine->VPBounds(iINON1,iINONn,nINON);
280 check = Standard_False;
283 else if (t == TopOpeBRep_ELLIPSE) {
284 Standard_Integer iINON1,iINONn,nINON;
285 myLine->VPBounds(iINON1,iINONn,nINON);
287 check = Standard_False;
290 const TopOpeBRep_VPointInter& A = myLine->VPoint(iINON1);
291 const TopOpeBRep_VPointInter& B = myLine->VPoint(iINONn);
292 Standard_Real parA = A.ParameterOnLine();
293 Standard_Real parB = B.ParameterOnLine();
294 Standard_Boolean conf = (fabs(parA-parB) < tol1);
296 check = Standard_False;
304 if (!check) { std::cout<<"# DEB CheckLine : rejet de ";TopOpeBRep::Print(t,std::cout);std::cout<<" a "<<nbvp<<" points"<<std::endl; }
310 //=======================================================================
311 //function : VP_Position
313 //=======================================================================
314 //void TopOpeBRep_FacesFiller::VP_Position(TopOpeBRep_FacesIntersector& FACINT)
315 void TopOpeBRep_FacesFiller::VP_Position(TopOpeBRep_FacesIntersector& )
317 for (myFacesIntersector->InitLine();
318 myFacesIntersector->MoreLine();
319 myFacesIntersector->NextLine()) {
320 TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine();
321 const TopOpeBRep_TypeLineCurve tl = L.TypeLineCurve();
322 Standard_Boolean ok = (tl == TopOpeBRep_RESTRICTION) ;
323 if ( ok ) VP_Position(L);
326 for (myFacesIntersector->InitLine();
327 myFacesIntersector->MoreLine();
328 myFacesIntersector->NextLine()) {
329 TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine();
330 const TopOpeBRep_TypeLineCurve tl = L.TypeLineCurve();
331 Standard_Boolean ok = (tl != TopOpeBRep_RESTRICTION) ;
332 if ( ok ) VP_Position(L);
336 //=======================================================================
337 //function : VP_Position
339 //=======================================================================
340 void TopOpeBRep_FacesFiller::VP_Position(TopOpeBRep_LineInter& L)
343 Standard_Boolean isrest = (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) ;
345 if (!isrest) VP_PositionOnL(L);
346 else VP_PositionOnR(L);
351 //=======================================================================
352 //function : VP_PositionOnL
354 //=======================================================================
355 void TopOpeBRep_FacesFiller::VP_PositionOnL(TopOpeBRep_LineInter& L)
357 TopOpeBRep_VPointInterIterator VPI(L);
358 Standard_Integer Lindex = L.Index();
359 TopOpeBRep_VPointInterClassifier VPC;
361 for (; VPI.More(); VPI.Next()) {
362 TopOpeBRep_VPointInter& VP = VPI.ChangeCurrentVP();
363 Standard_Integer VPsi = VP.ShapeIndex();
364 const gp_Pnt& P3D = VP.Value();
366 Standard_Boolean VPequalVPONRESTRICTION = Standard_False;
367 TopOpeBRep_FacesIntersector& FI = *((TopOpeBRep_FacesIntersector*)((void*)myFacesIntersector));
368 Standard_Integer iOL = 1,n = FI.NbLines();
369 for (iOL=1; iOL<=n; iOL++ ) {
370 if (iOL == Lindex ) continue;
371 TopOpeBRep_LineInter& OL = FI.ChangeLine(iOL);
372 VPequalVPONRESTRICTION = PequalVPonR(P3D,VPsi,VP,OL);
373 if ( VPequalVPONRESTRICTION ) break;
376 if ( !VPequalVPONRESTRICTION ) {
382 //=======================================================================
383 //function : VP_PositionOnR
385 //=======================================================================
386 void TopOpeBRep_FacesFiller::VP_PositionOnR(TopOpeBRep_LineInter& L)
388 TopOpeBRep_VPointInterClassifier VPC;
390 TopOpeBRep_VPointInterIterator VPI(L);
391 Standard_Integer Esi = (L.ArcIsEdge(1)) ? 1:2;
392 Standard_Integer OOEsi = (L.ArcIsEdge(1)) ? 2:1;
394 Standard_Boolean isline = Standard_False;
395 const TopoDS_Edge& earc = TopoDS::Edge(L.Arc());
396 Standard_Boolean hasc3d = FC2D_HasC3D(earc);
397 if (hasc3d) isline = FUN_tool_line(earc);
399 BRepAdaptor_Curve2d BAC2D;
400 if (Esi == 1) BAC2D.Initialize(earc,myF1);
401 else if (Esi == 2) BAC2D.Initialize(earc,myF2);
402 GeomAbs_CurveType t = BAC2D.GetType();
403 isline = (t == GeomAbs_Line);
406 for (; VPI.More(); VPI.Next()) {
407 TopOpeBRep_VPointInter& VP = VPI.ChangeCurrentVP();
409 Standard_Boolean isvertex = VP.IsVertex(Esi);
411 if (!isline) VP_Position(VP,VPC);
414 Standard_Boolean OOisvertex = VP.IsVertex(OOEsi);
416 if (!isline) VP_Position(VP,VPC);
420 const gp_Pnt& P = VP.Value();
421 Standard_Boolean arcisE = L.ArcIsEdge(Esi);
422 Standard_Boolean arcisOOE = L.ArcIsEdge(OOEsi);
425 Standard_Real paramC;Standard_Boolean paramCdef = FUN_projPonL(P,L,(*this),paramC);
427 const TopoDS_Edge& E = TopoDS::Edge(L.Arc());
428 VP.State(TopAbs_ON,Esi);
429 VP.EdgeON(E,paramC,Esi);
432 // throw Standard_ProgramError("VP_Position projection failed on E");
433 VP.ChangeKeep(Standard_False); // xpu051198
438 Standard_Real paramC;Standard_Boolean paramCdef = FUN_projPonL(P,L,(*this),paramC);
440 const TopoDS_Edge& OOE = TopoDS::Edge(L.Arc());
441 VP.State(TopAbs_ON,OOEsi);
442 VP.EdgeON(OOE,paramC,OOEsi);
445 // throw Standard_ProgramError("VP_Position projection failed on OOE");
446 VP.ChangeKeep(Standard_False); // xpu051198
452 //=======================================================================
453 //function : VP_Position
455 //=======================================================================
456 void TopOpeBRep_FacesFiller::VP_Position(TopOpeBRep_VPointInter& VP,TopOpeBRep_VPointInterClassifier& VPC)
458 Standard_Integer si = VP.ShapeIndex();
459 Standard_Boolean c1=Standard_False,c2=Standard_False;
461 if (si == 0) { c1 = Standard_True; c2 = Standard_True; }
462 else if (si == 1) { c1 = Standard_False; c2 = Standard_True; }
463 else if (si == 2) { c1 = Standard_True; c2 = Standard_False; }
464 else if (si == 3) { c1 = Standard_True; c2 = Standard_True; }
466 Standard_Boolean AssumeINON = Standard_False;
467 if (myLine) AssumeINON = (myLine->TypeLineCurve() != TopOpeBRep_RESTRICTION);
469 // modified by NIZHNY-MKK Fri Oct 27 14:50:28 2000.BEGIN
470 // Standard_Real tol = Precision::Confusion();
471 Standard_Real tol1, tol2;
472 tol1 = tol2 = Precision::Confusion();
473 myFacesIntersector->GetTolerances(tol1, tol2);
474 Standard_Real tol = (tol1 > tol2) ? tol1 : tol2;
475 // modified by NIZHNY-MKK Fri Oct 27 14:50:36 2000.END
477 if (c1) VPC.VPointPosition(myF1,VP,1,myPointClassifier,AssumeINON,tol);
478 if (c2) VPC.VPointPosition(myF2,VP,2,myPointClassifier,AssumeINON,tol);
481 //=======================================================================
482 //function : PequalVPonR
484 //=======================================================================
485 Standard_Boolean TopOpeBRep_FacesFiller::PequalVPonR(const gp_Pnt& P3D,const Standard_Integer VPsi,TopOpeBRep_VPointInter& VP,TopOpeBRep_LineInter& Lrest) const
487 const TopOpeBRep_TypeLineCurve tOL = Lrest.TypeLineCurve();
488 Standard_Boolean OLok = (tOL == TopOpeBRep_RESTRICTION) ;
489 if ( !OLok ) return Standard_False;
491 Standard_Boolean VPequalVPONRESTRICTION = Standard_False;
492 const TopoDS_Edge& EOL = TopoDS::Edge(Lrest.Arc());
493 Standard_Integer EOLsi = (Lrest.ArcIsEdge(1)) ? 1:2;
495 TopOpeBRep_VPointInterIterator VPIOL(Lrest);
496 for (; VPIOL.More(); VPIOL.Next()) {
497 TopOpeBRep_VPointInter& VPOL = VPIOL.ChangeCurrentVP();
498 Standard_Integer VPOLsi = VPOL.ShapeIndex();
500 Standard_Boolean VPOLisvertex = Standard_False;
501 VPOLisvertex = VPOL.IsVertex(1);
502 if (VPOLisvertex) continue;
504 Standard_Boolean diffsi = (VPOLsi != VPsi);
505 if ( diffsi ) continue;
507 TopAbs_State stateEsi = VPOL.State(EOLsi);
508 if (stateEsi != TopAbs_ON) continue;
510 const gp_Pnt& P3DOL = VPOL.Value();
511 Standard_Real tolE = BRep_Tool::Tolerance(EOL);
512 VPequalVPONRESTRICTION = P3DOL.IsEqual(P3D,tolE);
514 if ( VPequalVPONRESTRICTION ) {
515 Standard_Real paramCOL = VPOL.EdgeONParameter(EOLsi);
516 VP.State(TopAbs_ON,EOLsi);
517 VP.EdgeON(EOL,paramCOL,EOLsi);
521 return VPequalVPONRESTRICTION;
524 //=======================================================================
525 //function : FacesIntersector
527 //=======================================================================
528 TopOpeBRep_FacesIntersector& TopOpeBRep_FacesFiller::ChangeFacesIntersector()
530 return (*myFacesIntersector);
533 //=======================================================================
534 //function : HDataStructure
536 //=======================================================================
537 Handle(TopOpeBRepDS_HDataStructure) TopOpeBRep_FacesFiller::HDataStructure()
542 //=======================================================================
543 //function : DataStructure
545 //=======================================================================
546 TopOpeBRepDS_DataStructure& TopOpeBRep_FacesFiller::ChangeDataStructure()
551 //=======================================================================
554 //=======================================================================
555 const TopoDS_Face& TopOpeBRep_FacesFiller::Face(const Standard_Integer I) const
557 if (I == 1) return myF1;
558 else if (I == 2) return myF2;
559 throw Standard_ProgramError("FacesFiller::Face");
562 //=======================================================================
563 //function : FaceFaceTransition
565 //=======================================================================
566 const TopOpeBRepDS_Transition& TopOpeBRep_FacesFiller::FaceFaceTransition(const TopOpeBRep_LineInter& L,const Standard_Integer I) const
568 const TopOpeBRepDS_Transition& T = L.FaceFaceTransition(I);
572 //=======================================================================
573 //function : FaceFaceTransition
575 //=======================================================================
576 const TopOpeBRepDS_Transition& TopOpeBRep_FacesFiller::FaceFaceTransition(const Standard_Integer I) const
578 const TopOpeBRepDS_Transition& T = myLine->FaceFaceTransition(I);
582 TopOpeBRep_PFacesIntersector TopOpeBRep_FacesFiller::PFacesIntersectorDummy() const
583 {return myFacesIntersector;}
584 TopOpeBRepDS_PDataStructure TopOpeBRep_FacesFiller::PDataStructureDummy() const
586 TopOpeBRep_PLineInter TopOpeBRep_FacesFiller::PLineInterDummy() const
589 //=======================================================================
590 //function : SetTraceIndex
592 //=======================================================================
593 void TopOpeBRep_FacesFiller::SetTraceIndex(const Standard_Integer exF1,const Standard_Integer exF2)
599 //=======================================================================
600 //function : GetTraceIndex
602 //=======================================================================
603 void TopOpeBRep_FacesFiller::GetTraceIndex(Standard_Integer& exF1,Standard_Integer& exF2)const