Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-10-20 |
2 | // Created by: Yves FRICAUD | |
3 | // Copyright (c) 1995-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 | |
42cf5bc1 | 17 | |
18 | #include <Adaptor3d_Surface.hxx> | |
19 | #include <BRep_Builder.hxx> | |
20 | #include <BRep_Tool.hxx> | |
21 | #include <BRepAdaptor_Curve.hxx> | |
22 | #include <BRepAdaptor_Surface.hxx> | |
23 | #include <BRepOffset_Analyse.hxx> | |
7fd59977 | 24 | #include <BRepOffset_Interval.hxx> |
7fd59977 | 25 | #include <BRepOffset_ListIteratorOfListOfInterval.hxx> |
42cf5bc1 | 26 | #include <BRepOffset_Tool.hxx> |
7fd59977 | 27 | #include <BRepTools.hxx> |
42cf5bc1 | 28 | #include <Geom2d_Curve.hxx> |
29 | #include <Geom_Curve.hxx> | |
30 | #include <Geom_Surface.hxx> | |
7fd59977 | 31 | #include <gp.hxx> |
7fd59977 | 32 | #include <gp_Dir.hxx> |
33 | #include <gp_Pnt.hxx> | |
34 | #include <gp_Pnt2d.hxx> | |
42cf5bc1 | 35 | #include <gp_Vec.hxx> |
36 | #include <Precision.hxx> | |
7fd59977 | 37 | #include <TopExp.hxx> |
38 | #include <TopExp_Explorer.hxx> | |
7fd59977 | 39 | #include <TopoDS.hxx> |
42cf5bc1 | 40 | #include <TopoDS_Compound.hxx> |
7fd59977 | 41 | #include <TopoDS_Edge.hxx> |
42cf5bc1 | 42 | #include <TopoDS_Face.hxx> |
43 | #include <TopoDS_Shape.hxx> | |
44 | #include <TopoDS_Vertex.hxx> | |
7fd59977 | 45 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
46 | #include <TopTools_MapOfShape.hxx> | |
47 | ||
b0091bc9 | 48 | // |
49 | static void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d); | |
50 | // | |
51 | static BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, | |
52 | const TopoDS_Face& F1, | |
53 | const TopoDS_Face& F2, | |
54 | const Standard_Real SinTol, | |
55 | const Standard_Boolean CorrectPoint); | |
56 | // | |
d804b26d | 57 | static void CorrectOrientationOfTangent(gp_Vec& TangVec, |
58 | const TopoDS_Vertex& aVertex, | |
59 | const TopoDS_Edge& anEdge) | |
60 | { | |
61 | TopoDS_Vertex Vlast = TopExp::LastVertex(anEdge); | |
62 | if (aVertex.IsSame(Vlast)) | |
63 | TangVec.Reverse(); | |
64 | } | |
7fd59977 | 65 | //======================================================================= |
66 | //function : BRepOffset_Analyse | |
67 | //purpose : | |
68 | //======================================================================= | |
69 | ||
70 | BRepOffset_Analyse::BRepOffset_Analyse() | |
71 | :myDone(Standard_False) | |
72 | { | |
73 | } | |
74 | ||
75 | ||
76 | //======================================================================= | |
77 | //function : BRepOffset_Analyse | |
78 | //purpose : | |
79 | //======================================================================= | |
80 | ||
81 | BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S, | |
82 | const Standard_Real Angle) | |
83 | :myDone(Standard_False) | |
84 | { | |
85 | Perform( S, Angle); | |
86 | } | |
87 | ||
88 | //======================================================================= | |
89 | //function : EdgeAnlyse | |
90 | //purpose : | |
91 | //======================================================================= | |
92 | ||
93 | static void EdgeAnalyse(const TopoDS_Edge& E, | |
b0091bc9 | 94 | const TopoDS_Face& F1, |
95 | const TopoDS_Face& F2, | |
96 | const Standard_Real SinTol, | |
97 | BRepOffset_ListOfInterval& LI) | |
7fd59977 | 98 | { |
7fd59977 | 99 | |
7fd59977 | 100 | Standard_Real f,l; |
b0091bc9 | 101 | BRep_Tool::Range(E, F1, f, l); |
102 | BRepOffset_Interval I; | |
103 | I.First(f); I.Last(l); | |
104 | // | |
0d969553 | 105 | // Tangent if the regularity is at least G1. |
7fd59977 | 106 | if (BRep_Tool::HasContinuity(E,F1,F2)) { |
107 | if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) { | |
7fd59977 | 108 | I.Type(BRepOffset_Tangent); |
109 | LI.Append(I); | |
110 | return; | |
111 | } | |
112 | } | |
b0091bc9 | 113 | // |
114 | BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False); | |
115 | if(aType != BRepOffset_Tangent) | |
116 | { | |
117 | aType = DefineConnectType(E, F1, F2, SinTol, Standard_True); | |
7fd59977 | 118 | } |
b0091bc9 | 119 | I.Type(aType); |
7fd59977 | 120 | LI.Append(I); |
121 | } | |
122 | ||
123 | //======================================================================= | |
124 | //function : BuildAncestors | |
125 | //purpose : | |
126 | //======================================================================= | |
127 | ||
128 | static void BuildAncestors (const TopoDS_Shape& S, | |
129 | TopTools_IndexedDataMapOfShapeListOfShape& MA) | |
130 | { | |
131 | MA.Clear(); | |
132 | TopExp::MapShapesAndAncestors(S,TopAbs_VERTEX,TopAbs_EDGE,MA); | |
133 | TopExp::MapShapesAndAncestors(S,TopAbs_EDGE ,TopAbs_FACE,MA); | |
134 | ||
0d969553 | 135 | // Purge ancestors. |
7fd59977 | 136 | TopTools_MapOfShape Map; |
137 | for (Standard_Integer i = 1; i <= MA.Extent(); i++) { | |
138 | Map.Clear(); | |
139 | TopTools_ListOfShape& L = MA(i); | |
140 | TopTools_ListIteratorOfListOfShape it(L); | |
141 | while (it.More()) { | |
142 | if (!Map.Add(it.Value())) { | |
143 | L.Remove(it); | |
144 | } | |
145 | else { | |
146 | it.Next(); | |
147 | } | |
148 | } | |
149 | } | |
150 | } | |
151 | ||
152 | //======================================================================= | |
153 | //function : IsDone | |
154 | //purpose : | |
155 | //======================================================================= | |
156 | ||
157 | Standard_Boolean BRepOffset_Analyse::IsDone() const | |
158 | { | |
159 | return myDone; | |
160 | } | |
161 | ||
162 | ||
163 | //======================================================================= | |
164 | //function : Perform | |
165 | //purpose : | |
166 | //======================================================================= | |
167 | ||
168 | void BRepOffset_Analyse::Perform (const TopoDS_Shape& S, | |
169 | const Standard_Real Angle) | |
170 | { | |
171 | myShape = S; | |
172 | ||
173 | angle = Angle; | |
03383c97 | 174 | Standard_Real SinTol = Sin(Angle); |
7fd59977 | 175 | |
176 | // Build ancestors. | |
177 | BuildAncestors (S,ancestors); | |
178 | ||
179 | ||
180 | TopExp_Explorer Exp(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE); | |
181 | for ( ; Exp.More(); Exp.Next()) { | |
182 | const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); | |
183 | if (!mapEdgeType.IsBound(E)) { | |
184 | BRepOffset_ListOfInterval LI; | |
185 | mapEdgeType.Bind(E,LI); | |
186 | ||
187 | const TopTools_ListOfShape& L = Ancestors(E); | |
188 | if ( L.IsEmpty()) | |
189 | continue; | |
190 | ||
191 | if (L.Extent() == 2) { | |
192 | const TopoDS_Face& F1 = TopoDS::Face(L.First()); | |
193 | const TopoDS_Face& F2 = TopoDS::Face(L.Last ()); | |
194 | EdgeAnalyse(E,F1,F2,SinTol,mapEdgeType(E)); | |
195 | } | |
196 | else if (L.Extent() == 1) { | |
197 | Standard_Real U1,U2; | |
198 | const TopoDS_Face& F = TopoDS::Face(L.First()); | |
199 | BRep_Tool::Range(E,F,U1,U2); | |
200 | BRepOffset_Interval Inter(U1,U2,BRepOffset_Other); | |
201 | ||
202 | if (! BRepTools::IsReallyClosed(E,F)) { | |
203 | Inter.Type(BRepOffset_FreeBoundary); | |
204 | } | |
205 | mapEdgeType(E).Append(Inter); | |
206 | } | |
207 | else { | |
0797d9d3 | 208 | #ifdef OCCT_DEBUG |
7fd59977 | 209 | cout <<"edge shared by more than two faces"<<endl; |
210 | #endif | |
211 | } | |
212 | } | |
213 | } | |
214 | myDone = Standard_True; | |
215 | } | |
216 | ||
217 | //======================================================================= | |
218 | //function : Clear | |
219 | //purpose : | |
220 | //======================================================================= | |
221 | ||
222 | void BRepOffset_Analyse::Clear() | |
223 | { | |
224 | myDone = Standard_False; | |
225 | myShape .Nullify(); | |
226 | mapEdgeType.Clear(); | |
227 | ancestors .Clear(); | |
228 | } | |
229 | ||
230 | ||
231 | ||
232 | ||
233 | ||
234 | //======================================================================= | |
235 | //function : BRepOffset_ListOfInterval& | |
236 | //purpose : | |
237 | //======================================================================= | |
238 | ||
239 | const BRepOffset_ListOfInterval& BRepOffset_Analyse::Type(const TopoDS_Edge& E) | |
240 | const | |
241 | { | |
242 | return mapEdgeType (E); | |
243 | } | |
244 | ||
245 | ||
246 | //======================================================================= | |
247 | //function : Edges | |
248 | //purpose : | |
249 | //======================================================================= | |
250 | ||
251 | void BRepOffset_Analyse::Edges(const TopoDS_Vertex& V, | |
252 | const BRepOffset_Type T, | |
253 | TopTools_ListOfShape& LE) | |
254 | const | |
255 | { | |
256 | LE.Clear(); | |
257 | const TopTools_ListOfShape& L = Ancestors (V); | |
258 | TopTools_ListIteratorOfListOfShape it(L); | |
259 | ||
260 | for ( ;it.More(); it.Next()) { | |
261 | const TopoDS_Edge& E = TopoDS::Edge(it.Value()); | |
262 | TopoDS_Vertex V1,V2; | |
263 | BRepOffset_Tool::EdgeVertices (E,V1,V2); | |
264 | if (V1.IsSame(V)) { | |
265 | if (mapEdgeType(E).Last().Type() == T) | |
266 | LE.Append(E); | |
267 | } | |
268 | if (V2.IsSame(V)) { | |
269 | if (mapEdgeType(E).First().Type() == T) | |
270 | LE.Append(E); | |
271 | } | |
272 | } | |
273 | } | |
274 | ||
275 | ||
276 | //======================================================================= | |
277 | //function : Edges | |
278 | //purpose : | |
279 | //======================================================================= | |
280 | ||
281 | void BRepOffset_Analyse::Edges(const TopoDS_Face& F, | |
282 | const BRepOffset_Type T, | |
283 | TopTools_ListOfShape& LE) | |
284 | const | |
285 | { | |
286 | LE.Clear(); | |
287 | TopExp_Explorer exp(F, TopAbs_EDGE); | |
288 | ||
289 | for ( ;exp.More(); exp.Next()) { | |
290 | const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); | |
291 | ||
292 | const BRepOffset_ListOfInterval& Lint = Type(E); | |
293 | BRepOffset_ListIteratorOfListOfInterval it(Lint); | |
294 | for ( ;it.More(); it.Next()) { | |
295 | if (it.Value().Type() == T) LE.Append(E); | |
296 | } | |
297 | } | |
298 | } | |
299 | ||
300 | //======================================================================= | |
301 | //function : TangentEdges | |
302 | //purpose : | |
303 | //======================================================================= | |
304 | ||
305 | void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge , | |
306 | const TopoDS_Vertex& Vertex, | |
307 | TopTools_ListOfShape& Edges ) const | |
308 | { | |
309 | gp_Vec V,VRef; | |
310 | ||
311 | ||
312 | Standard_Real U,URef; | |
313 | BRepAdaptor_Curve C3d, C3dRef; | |
314 | ||
315 | URef = BRep_Tool::Parameter(Vertex,Edge); | |
316 | C3dRef = BRepAdaptor_Curve(Edge); | |
317 | VRef = C3dRef.DN(URef,1); | |
d804b26d | 318 | CorrectOrientationOfTangent(VRef, Vertex, Edge); |
7fd59977 | 319 | if (VRef.SquareMagnitude() < gp::Resolution()) return; |
320 | ||
321 | Edges.Clear(); | |
322 | ||
323 | const TopTools_ListOfShape& Anc = Ancestors(Vertex); | |
324 | TopTools_ListIteratorOfListOfShape it(Anc); | |
325 | for ( ; it.More(); it.Next()) { | |
326 | const TopoDS_Edge& CurE = TopoDS::Edge(it.Value()); | |
327 | if ( CurE.IsSame(Edge)) continue; | |
328 | U = BRep_Tool::Parameter(Vertex,CurE); | |
329 | C3d = BRepAdaptor_Curve(CurE); | |
330 | V = C3d.DN(U,1); | |
d804b26d | 331 | CorrectOrientationOfTangent(V, Vertex, CurE); |
7fd59977 | 332 | if (V.SquareMagnitude() < gp::Resolution()) continue; |
d804b26d | 333 | if (V.IsOpposite(VRef,angle)) { |
7fd59977 | 334 | Edges.Append(CurE); |
335 | } | |
336 | } | |
337 | } | |
338 | ||
339 | ||
340 | ||
341 | //======================================================================= | |
342 | //function : HasAncestor | |
343 | //purpose : | |
344 | //======================================================================= | |
345 | ||
346 | Standard_Boolean BRepOffset_Analyse::HasAncestor (const TopoDS_Shape& S) const | |
347 | { | |
348 | return ancestors.Contains(S); | |
349 | } | |
350 | ||
351 | ||
352 | //======================================================================= | |
353 | //function : Ancestors | |
354 | //purpose : | |
355 | //======================================================================= | |
356 | ||
357 | const TopTools_ListOfShape& BRepOffset_Analyse::Ancestors | |
358 | (const TopoDS_Shape& S) const | |
359 | { | |
360 | return ancestors.FindFromKey(S); | |
361 | } | |
362 | ||
363 | ||
364 | //======================================================================= | |
365 | //function : Explode | |
366 | //purpose : | |
367 | //======================================================================= | |
368 | ||
369 | void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List, | |
370 | const BRepOffset_Type T ) const | |
371 | { | |
372 | List.Clear(); | |
373 | BRep_Builder B; | |
374 | TopTools_MapOfShape Map; | |
375 | ||
376 | TopExp_Explorer Fexp; | |
377 | for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) { | |
378 | if ( Map.Add(Fexp.Current())) { | |
379 | TopoDS_Face Face = TopoDS::Face(Fexp.Current()); | |
380 | TopoDS_Compound Co; | |
381 | B.MakeCompound(Co); | |
382 | B.Add(Co,Face); | |
0d969553 Y |
383 | // add to Co all faces from the cloud of faces |
384 | // G1 created from <Face> | |
7fd59977 | 385 | AddFaces(Face,Co,Map,T); |
386 | List.Append(Co); | |
387 | } | |
388 | } | |
389 | } | |
390 | ||
391 | //======================================================================= | |
392 | //function : Explode | |
393 | //purpose : | |
394 | //======================================================================= | |
395 | ||
396 | void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List, | |
397 | const BRepOffset_Type T1, | |
398 | const BRepOffset_Type T2) const | |
399 | { | |
400 | List.Clear(); | |
401 | BRep_Builder B; | |
402 | TopTools_MapOfShape Map; | |
403 | ||
404 | TopExp_Explorer Fexp; | |
405 | for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) { | |
406 | if ( Map.Add(Fexp.Current())) { | |
407 | TopoDS_Face Face = TopoDS::Face(Fexp.Current()); | |
408 | TopoDS_Compound Co; | |
409 | B.MakeCompound(Co); | |
410 | B.Add(Co,Face); | |
0d969553 Y |
411 | // add to Co all faces from the cloud of faces |
412 | // G1 created from <Face> | |
7fd59977 | 413 | AddFaces(Face,Co,Map,T1,T2); |
414 | List.Append(Co); | |
415 | } | |
416 | } | |
417 | } | |
418 | ||
419 | ||
420 | //======================================================================= | |
421 | //function : AddFaces | |
422 | //purpose : | |
423 | //======================================================================= | |
424 | ||
425 | void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face, | |
426 | TopoDS_Compound& Co, | |
427 | TopTools_MapOfShape& Map, | |
428 | const BRepOffset_Type T) const | |
429 | { | |
430 | BRep_Builder B; | |
431 | TopExp_Explorer exp(Face,TopAbs_EDGE); | |
432 | for ( ; exp.More(); exp.Next()) { | |
433 | const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); | |
434 | const BRepOffset_ListOfInterval& LI = Type(E); | |
435 | if (!LI.IsEmpty() && LI.First().Type() == T) { | |
0d969553 | 436 | // so <NewFace> is attached to G1 by <Face> |
7fd59977 | 437 | const TopTools_ListOfShape& L = Ancestors(E); |
438 | if (L.Extent() == 2) { | |
439 | TopoDS_Face F1 = TopoDS::Face(L.First()); | |
440 | if ( F1.IsSame(Face)) | |
441 | F1 = TopoDS::Face(L.Last ()); | |
442 | if ( Map.Add(F1)) { | |
443 | B.Add(Co,F1); | |
444 | AddFaces(F1,Co,Map,T); | |
445 | } | |
446 | } | |
447 | } | |
448 | } | |
449 | } | |
450 | //======================================================================= | |
451 | //function : AddFaces | |
452 | //purpose : | |
453 | //======================================================================= | |
454 | ||
455 | void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face, | |
456 | TopoDS_Compound& Co, | |
457 | TopTools_MapOfShape& Map, | |
458 | const BRepOffset_Type T1, | |
459 | const BRepOffset_Type T2) const | |
460 | { | |
461 | BRep_Builder B; | |
462 | TopExp_Explorer exp(Face,TopAbs_EDGE); | |
463 | for ( ; exp.More(); exp.Next()) { | |
464 | const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); | |
465 | const BRepOffset_ListOfInterval& LI = Type(E); | |
466 | if (!LI.IsEmpty() && | |
467 | (LI.First().Type() == T1 || LI.First().Type() == T2)) { | |
0d969553 | 468 | // so <NewFace> is attached to G1 by <Face> |
7fd59977 | 469 | const TopTools_ListOfShape& L = Ancestors(E); |
470 | if (L.Extent() == 2) { | |
471 | TopoDS_Face F1 = TopoDS::Face(L.First()); | |
472 | if ( F1.IsSame(Face)) | |
473 | F1 = TopoDS::Face(L.Last ()); | |
474 | if ( Map.Add(F1)) { | |
475 | B.Add(Co,F1); | |
476 | AddFaces(F1,Co,Map,T1,T2); | |
477 | } | |
478 | } | |
479 | } | |
480 | } | |
481 | } | |
b0091bc9 | 482 | |
483 | //======================================================================= | |
484 | //function : Correct2dPoint | |
485 | //purpose : | |
486 | //======================================================================= | |
487 | void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d) | |
488 | { | |
489 | const Standard_Real coeff = 0.01; | |
490 | Standard_Real eps; | |
491 | Standard_Real u1, u2, v1, v2; | |
492 | if(theS.GetType() >= GeomAbs_BezierSurface) | |
493 | { | |
494 | u1 = theS.FirstUParameter(); | |
495 | u2 = theS.LastUParameter(); | |
496 | v1 = theS.FirstVParameter(); | |
497 | v2 = theS.LastVParameter(); | |
498 | if(!(Precision::IsInfinite(u1) || Precision::IsInfinite(u2))) | |
499 | { | |
500 | eps = Max(coeff*(u2-u1), Precision::PConfusion()); | |
501 | if(Abs(theP2d.X()-u1) < eps) | |
502 | { | |
503 | theP2d.SetX(u1 + eps); | |
504 | } | |
505 | if(Abs(theP2d.X()-u2) < eps) | |
506 | { | |
507 | theP2d.SetX(u2 - eps); | |
508 | } | |
509 | } | |
510 | if(!(Precision::IsInfinite(v1) || Precision::IsInfinite(v2))) | |
511 | { | |
512 | eps = Max(coeff*(v2-v1), Precision::PConfusion()); | |
513 | if(Abs(theP2d.Y()-v1) < eps) | |
514 | { | |
515 | theP2d.SetY(v1 + eps); | |
516 | } | |
517 | if(Abs(theP2d.Y()-v2) < eps) | |
518 | { | |
519 | theP2d.SetY(v2 - eps); | |
520 | } | |
521 | } | |
522 | } | |
523 | } | |
524 | ||
525 | //======================================================================= | |
526 | //function : DefineConnectType | |
527 | //purpose : | |
528 | //======================================================================= | |
529 | BRepOffset_Type DefineConnectType(const TopoDS_Edge& E, | |
530 | const TopoDS_Face& F1, | |
531 | const TopoDS_Face& F2, | |
532 | const Standard_Real SinTol, | |
533 | const Standard_Boolean CorrectPoint) | |
534 | { | |
535 | TopLoc_Location L; | |
536 | Standard_Real f,l; | |
537 | ||
538 | BRepAdaptor_Surface S1(F1), S2(F2); | |
539 | Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l); | |
540 | Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l); | |
541 | ||
542 | BRepAdaptor_Curve C(E); | |
543 | f = C.FirstParameter(); | |
544 | l = C.LastParameter(); | |
545 | // | |
546 | Standard_Real ParOnC = 0.5*(f+l); | |
547 | gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation()); | |
548 | if (T1.SquareMagnitude() > gp::Resolution()) { | |
549 | T1.Normalize(); | |
550 | } | |
551 | ||
552 | if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) { | |
553 | T1.Reverse(); | |
554 | } | |
555 | if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse(); | |
556 | ||
557 | gp_Pnt2d P = C1->Value(ParOnC); | |
558 | gp_Pnt P3; | |
559 | gp_Vec D1U,D1V; | |
560 | ||
561 | if(CorrectPoint) | |
562 | Correct2dPoint(S1, P); | |
563 | // | |
564 | S1.D1(P.X(),P.Y(),P3,D1U,D1V); | |
565 | gp_Vec DN1(D1U^D1V); | |
566 | if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse(); | |
567 | ||
568 | P = C2->Value(ParOnC); | |
569 | if(CorrectPoint) | |
570 | Correct2dPoint(S2, P); | |
571 | S2.D1(P.X(),P.Y(),P3,D1U,D1V); | |
572 | gp_Vec DN2(D1U^D1V); | |
573 | if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse(); | |
574 | ||
575 | DN1.Normalize(); | |
576 | DN2.Normalize(); | |
577 | ||
578 | gp_Vec ProVec = DN1^DN2; | |
579 | Standard_Real NormProVec = ProVec.Magnitude(); | |
580 | ||
581 | if (Abs(NormProVec) < SinTol) { | |
582 | // plane | |
583 | if (DN1.Dot(DN2) > 0) { | |
584 | //Tangent | |
585 | return BRepOffset_Tangent; | |
586 | } | |
587 | else { | |
588 | //Mixed not finished! | |
589 | #ifdef OCCT_DEBUG | |
590 | cout <<" faces locally mixed"<<endl; | |
591 | #endif | |
592 | return BRepOffset_Convex; | |
593 | } | |
594 | } | |
595 | else { | |
596 | if (NormProVec > gp::Resolution()) | |
597 | ProVec.Normalize(); | |
598 | Standard_Real Prod = T1.Dot(DN1^DN2); | |
599 | if (Prod > 0.) { | |
600 | // | |
601 | return BRepOffset_Convex; | |
602 | } | |
603 | else { | |
604 | //reenters | |
605 | return BRepOffset_Concave; | |
606 | } | |
607 | } | |
608 | } |