1 // Created on: 1998-03-23
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1998-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.
17 #include <gp_Vec2d.hxx>
20 #include <TopOpeBRepTool_2d.hxx>
21 #include <BRep_Tool.hxx>
22 #include <Geom_Curve.hxx>
23 #include <ProjLib_ProjectedCurve.hxx>
24 #include <Geom_Surface.hxx>
25 #include <BRepAdaptor_Surface.hxx>
26 #include <BRepAdaptor_Curve.hxx>
27 #include <BRepAdaptor_HSurface.hxx>
28 #include <BRepAdaptor_HCurve.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <GeomAdaptor_HCurve.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <TopOpeBRepTool_CurveTool.hxx>
33 #include <TopOpeBRepTool_DataMapOfShapeListOfC2DF.hxx>
34 #include <TopOpeBRepTool_C2DF.hxx>
35 #include <TopOpeBRepTool_ListOfC2DF.hxx>
36 #include <TopOpeBRepTool_ListIteratorOfListOfC2DF.hxx>
37 #include <TopOpeBRepTool_tol.hxx>
38 #include <TopOpeBRepTool_EXPORT.hxx>
39 #include <TopOpeBRepTool_TOOL.hxx>
42 #include <TopOpeBRepTool_DRAW.hxx>
43 #include <Geom2d_Curve.hxx>
47 void debc2dnull(void) {}
48 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceC2D();
51 // structure e -> C2D/F
52 static TopOpeBRepTool_DataMapOfShapeListOfC2DF *GLOBAL_pmosloc2df = NULL;
53 static Standard_Integer GLOBAL_C2D_i = 0; // DEB
56 static TopTools_IndexedDataMapOfShapeListOfShape *GLOBAL_pidmoslosc2df = NULL;
57 static TopoDS_Face *GLOBAL_pFc2df = NULL;
58 static TopoDS_Shape *GLOBAL_pS1c2df = NULL;
59 static TopoDS_Shape *GLOBAL_pS2c2df = NULL;
61 Standard_EXPORT Handle(Geom2d_Curve) MakePCurve(const ProjLib_ProjectedCurve& PC);
63 // ------------------------------------------------------------------------------------
64 static const TopoDS_Face& FC2D_FancestorE(const TopoDS_Edge& E)
66 if (GLOBAL_pmosloc2df == NULL) GLOBAL_pmosloc2df = new TopOpeBRepTool_DataMapOfShapeListOfC2DF();
67 Standard_Integer ancemp = (*GLOBAL_pidmoslosc2df).Extent();
69 TopExp::MapShapesAndAncestors(*GLOBAL_pS1c2df,TopAbs_EDGE,TopAbs_FACE,(*GLOBAL_pidmoslosc2df));
70 TopExp::MapShapesAndAncestors(*GLOBAL_pS2c2df,TopAbs_EDGE,TopAbs_FACE,(*GLOBAL_pidmoslosc2df));
72 Standard_Boolean Eb = (*GLOBAL_pidmoslosc2df).Contains(E);
73 if ( !Eb ) return *GLOBAL_pFc2df;
74 const TopTools_ListOfShape& lf = (*GLOBAL_pidmoslosc2df).FindFromKey(E);
75 if (lf.IsEmpty()) return *GLOBAL_pFc2df;
76 const TopoDS_Face& F = TopoDS::Face(lf.First());
80 // ------------------------------------------------------------------------------------
81 Standard_EXPORT int FC2D_Prepare(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
83 if (GLOBAL_pmosloc2df == NULL) GLOBAL_pmosloc2df = new TopOpeBRepTool_DataMapOfShapeListOfC2DF();
84 GLOBAL_pmosloc2df->Clear();
87 if (GLOBAL_pidmoslosc2df == NULL) GLOBAL_pidmoslosc2df = new TopTools_IndexedDataMapOfShapeListOfShape();
88 GLOBAL_pidmoslosc2df->Clear();
90 if (GLOBAL_pFc2df == NULL) GLOBAL_pFc2df = new TopoDS_Face();
91 GLOBAL_pFc2df->Nullify();
93 if (GLOBAL_pS1c2df == NULL) GLOBAL_pS1c2df = new TopoDS_Shape();
96 if (GLOBAL_pS2c2df == NULL) GLOBAL_pS2c2df = new TopoDS_Shape();
102 // ------------------------------------------------------------------------------------
103 Standard_EXPORT Standard_Boolean FC2D_HasC3D(const TopoDS_Edge& E)
105 TopLoc_Location loc; Standard_Real f3d,l3d; Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,loc,f3d,l3d);
106 Standard_Boolean b = (!C3D.IsNull());
110 // ------------------------------------------------------------------------------------
111 Standard_EXPORT Standard_Boolean FC2D_HasCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F)
113 Handle(Geom2d_Curve) C2D;
114 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D);
115 Standard_Boolean hasnew = FC2D_HasNewCurveOnSurface(E,F,C2D);
116 Standard_Boolean b = hasold || hasnew;
120 // ------------------------------------------------------------------------------------
121 Standard_EXPORT Standard_Boolean FC2D_HasOldCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Handle(Geom2d_Curve)& C2D,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol)
123 Standard_Boolean hasold = Standard_False;
124 tol = BRep_Tool::Tolerance(E);
125 C2D = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
126 hasold = (!C2D.IsNull());
129 Standard_EXPORT Standard_Boolean FC2D_HasOldCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Handle(Geom2d_Curve)& C2D)
130 { Standard_Real f2d,l2d,tol; Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f2d,l2d,tol); return hasold;
133 // ------------------------------------------------------------------------------------
134 static TopOpeBRepTool_C2DF* FC2D_PNewCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F)
136 TopOpeBRepTool_C2DF* pc2df = NULL;
137 if (GLOBAL_pmosloc2df == NULL) return NULL;
138 Standard_Boolean Eisb = GLOBAL_pmosloc2df->IsBound(E);
139 if (!Eisb) return NULL;
140 TopOpeBRepTool_ListIteratorOfListOfC2DF it(GLOBAL_pmosloc2df->Find(E));
141 for(;it.More();it.Next()) {
142 const TopOpeBRepTool_C2DF& c2df = it.Value();
143 Standard_Boolean isf = c2df.IsFace(F);
145 pc2df = (TopOpeBRepTool_C2DF*)&c2df;
151 Standard_EXPORT Standard_Boolean FC2D_HasNewCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Handle(Geom2d_Curve)& C2D,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol)
153 const TopOpeBRepTool_C2DF* pc2df = FC2D_PNewCurveOnSurface(E,F);
154 Standard_Boolean hasnew = (pc2df != NULL);
155 if (hasnew) C2D = pc2df->PC(f2d,l2d,tol);
158 Standard_EXPORT Standard_Boolean FC2D_HasNewCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Handle(Geom2d_Curve)& C2D)
159 { Standard_Real f2d,l2d,tol; Standard_Boolean b = FC2D_HasNewCurveOnSurface(E,F,C2D,f2d,l2d,tol); return b;
162 // ------------------------------------------------------------------------------------
163 Standard_Integer FC2D_AddNewCurveOnSurface(Handle(Geom2d_Curve) C2D,const TopoDS_Edge& E,const TopoDS_Face& F,const Standard_Real& f2d,const Standard_Real& l2d,const Standard_Real& tol)
165 if (C2D.IsNull()) return 1;
166 TopOpeBRepTool_C2DF c2df(C2D,f2d,l2d,tol,F);
167 if (GLOBAL_pmosloc2df == NULL) return 1;
168 TopOpeBRepTool_ListOfC2DF thelist;
169 GLOBAL_pmosloc2df->Bind(E, thelist);
170 TopOpeBRepTool_ListOfC2DF& lc2df = GLOBAL_pmosloc2df->ChangeFind(E);
175 // ------------------------------------------------------------------------------------
176 static Handle(Geom2d_Curve) FC2D_make2d(const TopoDS_Edge& E,const TopoDS_Face& F,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol,const Standard_Boolean trim3d = Standard_False);
177 static Handle(Geom2d_Curve) FC2D_make2d(const TopoDS_Edge& E,const TopoDS_Face& F,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol,const Standard_Boolean trim3d)
179 Handle(Geom2d_Curve) C2D = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
180 if (!C2D.IsNull()) return C2D;
183 Standard_Real f3d,l3d;TopLoc_Location eloc;
184 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E,eloc,f3d,l3d);
185 Standard_Boolean hasC3D = (!C1.IsNull());
188 Standard_Boolean elocid = eloc.IsIdentity();
189 Handle(Geom_Curve) C2;
190 if (elocid ) C2 = C1;
191 else C2 = Handle(Geom_Curve)::DownCast(C1->Transformed(eloc.Transformation()));
192 Standard_Real f=0.,l=0.;
193 if (trim3d) {f=f3d; l=l3d;}
194 C2D = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F,C2,tol,f,l);
195 f2d = f3d; l2d = l3d;
199 // E sans courbe 2d sur F, E sans courbe 3d
200 // une face accedant a E : FE
201 const TopoDS_Face& FE = FC2D_FancestorE(E);
202 if (FE.IsNull()) return C2D;
203 Standard_Boolean compminmaxUV = Standard_False;
204 BRepAdaptor_Surface BAS(F,compminmaxUV);
205 Handle(BRepAdaptor_HSurface) BAHS = new BRepAdaptor_HSurface(BAS);
206 BRepAdaptor_Curve AC(E,FE);
207 Handle(BRepAdaptor_HCurve) AHC = new BRepAdaptor_HCurve(AC);
208 Standard_Real tolin; FTOL_FaceTolerances3d(F,FE,tolin);
209 ProjLib_ProjectedCurve projcurv(BAHS,AHC,tolin);
210 C2D = MakePCurve(projcurv);
211 Standard_Real f,l; BRep_Tool::Range(E,f,l);
216 if (TopOpeBRepTool_GettraceC2D() && C2D.IsNull()) {
217 cout<<"#FC2D_make2d1 --> PCurve IsNull"<<endl;
224 // ------------------------------------------------------------------------------------
225 //modified by NIZHNY-MZV Mon Oct 4 10:37:36 1999
226 Standard_EXPORT Handle(Geom2d_Curve) FC2D_MakeCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Standard_Real& f,Standard_Real& l,Standard_Real& tol,const Standard_Boolean trim3d)
229 if (TopOpeBRepTool_GettraceC2D()) {
230 cout<<"\n#FC2D_MakeCurveOnSurface : "<<endl;
231 TCollection_AsciiString fnam("c2df");GLOBAL_C2D_i++;fnam=fnam+GLOBAL_C2D_i;FDRAW_DINS("",F,fnam,"");
232 TCollection_AsciiString enam("c2de");GLOBAL_C2D_i++;enam=enam+GLOBAL_C2D_i;FDRAW_DINE(" ",E,enam,"\n");
233 cout.flush(); debc2dnull();
237 Handle(Geom2d_Curve) C2D = FC2D_make2d(E,F,f,l,tol,trim3d);
238 FC2D_AddNewCurveOnSurface(C2D,E,F,f,l,tol);
242 // ------------------------------------------------------------------------------------
243 Standard_EXPORT Handle(Geom2d_Curve) FC2D_CurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Standard_Real& f,Standard_Real& l,Standard_Real& tol,const Standard_Boolean trim3d)
245 Handle(Geom2d_Curve) C2D;
246 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f,l,tol);
250 Standard_Boolean hasnew = FC2D_HasNewCurveOnSurface(E,F,C2D,f,l,tol);
254 C2D = FC2D_MakeCurveOnSurface(E,F,f,l,tol,trim3d);
258 // ------------------------------------------------------------------------------------
259 Standard_EXPORT Handle(Geom2d_Curve) FC2D_EditableCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,Standard_Real& f,Standard_Real& l,Standard_Real& tol,const Standard_Boolean trim3d)
261 Standard_Boolean hasold = Standard_False;
263 Handle(Geom2d_Curve) C2D;
264 hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f,l,tol);
266 Handle(Geom2d_Curve) copC2D = Handle(Geom2d_Curve)::DownCast(C2D->Copy());
270 Standard_Boolean hasnew = Standard_False;
272 Handle(Geom2d_Curve) newC2D;
273 hasnew = FC2D_HasNewCurveOnSurface(E,F,newC2D,f,l,tol);
278 Handle(Geom2d_Curve) makC2D = FC2D_MakeCurveOnSurface(E,F,f,l,tol,trim3d);
282 // ------------------------------------------------------------------------------------
283 static void FC2D_translate(Handle(Geom2d_Curve) C2D,
284 // const TopoDS_Edge& E,
286 const TopoDS_Face& F,
287 const TopoDS_Edge& EF)
289 TopLoc_Location sloc; const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F,sloc);
290 Standard_Boolean isperio = S1->IsUPeriodic() || S1->IsVPeriodic();
291 gp_Dir2d d2d; gp_Pnt2d O2d; Standard_Boolean isuiso,isviso;
292 Standard_Boolean uviso = TopOpeBRepTool_TOOL::UVISO(C2D,isuiso,isviso,d2d,O2d);
293 Standard_Boolean EFnull = EF.IsNull();
295 if (isperio && uviso && !EFnull) {
296 // C2D prend comme origine dans F l'origine de la pcurve de EF dans F
297 TopoDS_Face FFOR = F;
298 FFOR.Orientation(TopAbs_FORWARD);
299 gp_Pnt2d p1,p2; BRep_Tool::UVPoints(EF,FFOR,p1,p2);
300 Standard_Real pEF = isuiso ? p1.X() : p1.Y();
301 Standard_Real pC2D = isuiso ? O2d.X() : O2d.Y();
302 Standard_Real factor = pEF - pC2D;
303 Standard_Boolean b = (Abs(factor) > 1.e-6);
305 gp_Vec2d transl(1.,0.); if (isviso) transl = gp_Vec2d(0.,1.);
306 transl.Multiply(factor);
307 C2D->Translate(transl);
312 // ------------------------------------------------------------------------------------
313 static Handle(Geom2d_Curve) FC2D_make2d(const TopoDS_Edge& E,const TopoDS_Face& F,const TopoDS_Edge& EF,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol,const Standard_Boolean trim3d = Standard_False);
314 static Handle(Geom2d_Curve) FC2D_make2d(const TopoDS_Edge& E,const TopoDS_Face& F,const TopoDS_Edge& EF,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol,const Standard_Boolean trim3d)
316 Handle(Geom2d_Curve) C2D = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
317 if (!C2D.IsNull()) return C2D;
320 Standard_Real f3d,l3d;TopLoc_Location eloc;
321 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E,eloc,f3d,l3d);
322 Standard_Boolean hasC3D = (!C1.IsNull());
325 Standard_Boolean elocid = eloc.IsIdentity();
326 Handle(Geom_Curve) C2;
327 if (elocid ) C2 = C1;
328 else C2 = Handle(Geom_Curve)::DownCast(C1->Transformed(eloc.Transformation()));
329 Standard_Real f=0.,l=0.;
330 if (trim3d) {f=f3d; l=l3d;}
331 C2D = TopOpeBRepTool_CurveTool::MakePCurveOnFace(F,C2,tol,f,l);
332 f2d = f3d; l2d = l3d;
333 FC2D_translate(C2D,E,F,EF);
337 // E sans courbe 2d sur F, E sans courbe 3d
338 // une face accedant a E : FE
339 const TopoDS_Face& FE = FC2D_FancestorE(E);
340 if (FE.IsNull()) return C2D;
341 Standard_Boolean compminmaxUV = Standard_False;
342 BRepAdaptor_Surface BAS(F,compminmaxUV);
343 Handle(BRepAdaptor_HSurface) BAHS = new BRepAdaptor_HSurface(BAS);
344 BRepAdaptor_Curve AC(E,FE);
345 Handle(BRepAdaptor_HCurve) AHC = new BRepAdaptor_HCurve(AC);
346 Standard_Real tolin; FTOL_FaceTolerances3d(F,FE,tolin);
347 ProjLib_ProjectedCurve projcurv(BAHS,AHC,tolin);
348 C2D = MakePCurve(projcurv);
349 Standard_Real f,l; BRep_Tool::Range(E,f,l);
351 FC2D_translate(C2D,E,F,EF);
355 if (TopOpeBRepTool_GettraceC2D() && C2D.IsNull()) {
356 cout<<"#FC2D_make2d2 --> PCurve IsNull"<<endl;
363 // ------------------------------------------------------------------------------------
364 Standard_EXPORT Handle(Geom2d_Curve) FC2D_CurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F,const TopoDS_Edge& EF,Standard_Real& f2d,Standard_Real& l2d,Standard_Real& tol,const Standard_Boolean trim3d)
366 Handle(Geom2d_Curve) C2D;
368 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f2d,l2d,tol);
369 if (hasold) return C2D;
371 TopOpeBRepTool_C2DF* pc2df = FC2D_PNewCurveOnSurface(E,F);
373 C2D = pc2df->PC(f2d,l2d,tol);
374 FC2D_translate(C2D,E,F,EF);
375 pc2df->SetPC(C2D,f2d,l2d,tol);
380 if (TopOpeBRepTool_GettraceC2D()) {
381 cout<<"\n#FC2D_CurveOnSurface : "<<endl;
382 TCollection_AsciiString fnam("c2df");GLOBAL_C2D_i++;fnam=fnam+GLOBAL_C2D_i;FDRAW_DINS("",F,fnam,"");
383 TCollection_AsciiString enam("c2de");GLOBAL_C2D_i++;enam=enam+GLOBAL_C2D_i;FDRAW_DINE(" ",E,enam,"\n");
384 cout.flush();debc2dnull();
388 C2D = FC2D_make2d(E,F,EF,f2d,l2d,tol,trim3d);
389 FC2D_AddNewCurveOnSurface(C2D,E,F,f2d,l2d,tol);