0024947: Redesign OCCT legacy type system -- automatic
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_2d.cxx
CommitLineData
b311480e 1// Created on: 1998-03-23
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <gp_Vec2d.hxx>
18#include <TopoDS.hxx>
19#include <TopExp.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>
40
41#ifdef DRAW
42#include <TopOpeBRepTool_DRAW.hxx>
ec357c5c 43#include <Geom2d_Curve.hxx>
7fd59977 44#endif
45
0797d9d3 46#ifdef OCCT_DEBUG
7fd59977 47void debc2dnull(void) {}
48Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceC2D();
49#endif
50
51// structure e -> C2D/F
52static TopOpeBRepTool_DataMapOfShapeListOfC2DF *GLOBAL_pmosloc2df = NULL;
53static Standard_Integer GLOBAL_C2D_i = 0; // DEB
54
55// structure ancetre
56static TopTools_IndexedDataMapOfShapeListOfShape *GLOBAL_pidmoslosc2df = NULL;
57static TopoDS_Face *GLOBAL_pFc2df = NULL;
58static TopoDS_Shape *GLOBAL_pS1c2df = NULL;
59static TopoDS_Shape *GLOBAL_pS2c2df = NULL;
60
61Standard_EXPORT Handle(Geom2d_Curve) MakePCurve(const ProjLib_ProjectedCurve& PC);
62
63// ------------------------------------------------------------------------------------
64static const TopoDS_Face& FC2D_FancestorE(const TopoDS_Edge& E)
65{
66 if (GLOBAL_pmosloc2df == NULL) GLOBAL_pmosloc2df = new TopOpeBRepTool_DataMapOfShapeListOfC2DF();
67 Standard_Integer ancemp = (*GLOBAL_pidmoslosc2df).Extent();
68 if (ancemp == 0) {
69 TopExp::MapShapesAndAncestors(*GLOBAL_pS1c2df,TopAbs_EDGE,TopAbs_FACE,(*GLOBAL_pidmoslosc2df));
70 TopExp::MapShapesAndAncestors(*GLOBAL_pS2c2df,TopAbs_EDGE,TopAbs_FACE,(*GLOBAL_pidmoslosc2df));
71 }
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());
77 return F;
78}
79
80// ------------------------------------------------------------------------------------
81Standard_EXPORT int FC2D_Prepare(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
82{
83 if (GLOBAL_pmosloc2df == NULL) GLOBAL_pmosloc2df = new TopOpeBRepTool_DataMapOfShapeListOfC2DF();
84 GLOBAL_pmosloc2df->Clear();
85 GLOBAL_C2D_i = 0;
86
87 if (GLOBAL_pidmoslosc2df == NULL) GLOBAL_pidmoslosc2df = new TopTools_IndexedDataMapOfShapeListOfShape();
88 GLOBAL_pidmoslosc2df->Clear();
89
90 if (GLOBAL_pFc2df == NULL) GLOBAL_pFc2df = new TopoDS_Face();
91 GLOBAL_pFc2df->Nullify();
92
93 if (GLOBAL_pS1c2df == NULL) GLOBAL_pS1c2df = new TopoDS_Shape();
94 *GLOBAL_pS1c2df = S1;
95
96 if (GLOBAL_pS2c2df == NULL) GLOBAL_pS2c2df = new TopoDS_Shape();
97 *GLOBAL_pS2c2df = S2;
98
99 return 0;
100}
101
102// ------------------------------------------------------------------------------------
103Standard_EXPORT Standard_Boolean FC2D_HasC3D(const TopoDS_Edge& E)
104{
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());
107 return b;
108}
109
110// ------------------------------------------------------------------------------------
111Standard_EXPORT Standard_Boolean FC2D_HasCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F)
112{
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;
117 return b;
118}
119
120// ------------------------------------------------------------------------------------
121Standard_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)
122{
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());
127 return hasold;
128}
129Standard_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;
131}
132
133// ------------------------------------------------------------------------------------
134static TopOpeBRepTool_C2DF* FC2D_PNewCurveOnSurface(const TopoDS_Edge& E,const TopoDS_Face& F)
135{
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);
144 if (isf) {
145 pc2df = (TopOpeBRepTool_C2DF*)&c2df;
146 break;
147 }
148 }
149 return pc2df;
150}
151Standard_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)
152{
153 const TopOpeBRepTool_C2DF* pc2df = FC2D_PNewCurveOnSurface(E,F);
154 Standard_Boolean hasnew = (pc2df != NULL);
155 if (hasnew) C2D = pc2df->PC(f2d,l2d,tol);
156 return hasnew;
157}
158Standard_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;
160}
161
162// ------------------------------------------------------------------------------------
163Standard_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)
164{
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);
171 lc2df.Append(c2df);
172 return 0;
173}
174
175// ------------------------------------------------------------------------------------
176static 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);
177static 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)
178{
179 Handle(Geom2d_Curve) C2D = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
180 if (!C2D.IsNull()) return C2D;
181
182 // pas de 2D
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());
186
187 if ( hasC3D ) {
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;
196 return C2D;
197 }
198 else {
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);
212 f2d = f; l2d = l;
213 }
214
0797d9d3 215#ifdef OCCT_DEBUG
7fd59977 216 if (TopOpeBRepTool_GettraceC2D() && C2D.IsNull()) {
217 cout<<"#FC2D_make2d1 --> PCurve IsNull"<<endl;
218 }
219#endif
220
221 return C2D;
222} // make2d1
223
224// ------------------------------------------------------------------------------------
225//modified by NIZHNY-MZV Mon Oct 4 10:37:36 1999
226Standard_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)
227{
228#ifdef DRAW
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();
234 }
235#endif
236
237 Handle(Geom2d_Curve) C2D = FC2D_make2d(E,F,f,l,tol,trim3d);
238 FC2D_AddNewCurveOnSurface(C2D,E,F,f,l,tol);
239 return C2D;
240}
241
242// ------------------------------------------------------------------------------------
243Standard_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)
244{
245 Handle(Geom2d_Curve) C2D;
246 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f,l,tol);
247 if (hasold) {
248 return C2D;
249 }
250 Standard_Boolean hasnew = FC2D_HasNewCurveOnSurface(E,F,C2D,f,l,tol);
251 if (hasnew) {
252 return C2D;
253 }
254 C2D = FC2D_MakeCurveOnSurface(E,F,f,l,tol,trim3d);
255 return C2D;
256}
257
258// ------------------------------------------------------------------------------------
259Standard_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)
260{
261 Standard_Boolean hasold = Standard_False;
262 {
263 Handle(Geom2d_Curve) C2D;
264 hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f,l,tol);
265 if (hasold) {
266 Handle(Geom2d_Curve) copC2D = Handle(Geom2d_Curve)::DownCast(C2D->Copy());
267 return copC2D;
268 }
269 }
270 Standard_Boolean hasnew = Standard_False;
271 {
272 Handle(Geom2d_Curve) newC2D;
273 hasnew = FC2D_HasNewCurveOnSurface(E,F,newC2D,f,l,tol);
274 if (hasnew) {
275 return newC2D;
276 }
277 }
278 Handle(Geom2d_Curve) makC2D = FC2D_MakeCurveOnSurface(E,F,f,l,tol,trim3d);
279 return makC2D;
280}
281
282// ------------------------------------------------------------------------------------
283static void FC2D_translate(Handle(Geom2d_Curve) C2D,
284// const TopoDS_Edge& E,
285 const TopoDS_Edge& ,
286 const TopoDS_Face& F,
287 const TopoDS_Edge& EF)
288{
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();
294
295 if (isperio && uviso && !EFnull) {
296 // C2D prend comme origine dans F l'origine de la pcurve de EF dans F
7fd59977 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);
304 if ( b ) {
305 gp_Vec2d transl(1.,0.); if (isviso) transl = gp_Vec2d(0.,1.);
306 transl.Multiply(factor);
307 C2D->Translate(transl);
308 }
309 }
310}
311
312// ------------------------------------------------------------------------------------
313static 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);
314static 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)
315{
316 Handle(Geom2d_Curve) C2D = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
317 if (!C2D.IsNull()) return C2D;
318
319 // pas de 2D
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());
323
324 if ( hasC3D ) {
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);
334 return C2D;
335 }
336 else {
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);
350 f2d = f; l2d = l;
351 FC2D_translate(C2D,E,F,EF);
352 }
353
0797d9d3 354#ifdef OCCT_DEBUG
7fd59977 355 if (TopOpeBRepTool_GettraceC2D() && C2D.IsNull()) {
356 cout<<"#FC2D_make2d2 --> PCurve IsNull"<<endl;
357 }
358#endif
359
360 return C2D;
361} // make2d2
362
363// ------------------------------------------------------------------------------------
364Standard_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)
365{
366 Handle(Geom2d_Curve) C2D;
367
368 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,C2D,f2d,l2d,tol);
369 if (hasold) return C2D;
370
371 TopOpeBRepTool_C2DF* pc2df = FC2D_PNewCurveOnSurface(E,F);
372 if (pc2df != NULL) {
373 C2D = pc2df->PC(f2d,l2d,tol);
374 FC2D_translate(C2D,E,F,EF);
375 pc2df->SetPC(C2D,f2d,l2d,tol);
376 return C2D;
377 }
378
379#ifdef DRAW
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();
385 }
386#endif
387
388 C2D = FC2D_make2d(E,F,EF,f2d,l2d,tol,trim3d);
389 FC2D_AddNewCurveOnSurface(C2D,E,F,f2d,l2d,tol);
390 return C2D;
391}