0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / LocOpe / LocOpe_Gluer.cxx
CommitLineData
b311480e 1// Created on: 1996-01-30
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1996-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
7fd59977 17
42cf5bc1 18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepExtrema_ExtPF.hxx>
21#include <Extrema_ExtPS.hxx>
22#include <Geom2d_Curve.hxx>
23#include <Geom_Surface.hxx>
24#include <GeomAdaptor_Surface.hxx>
25#include <gp_Pnt2d.hxx>
26#include <gp_Vec.hxx>
27#include <LocOpe.hxx>
28#include <LocOpe_Generator.hxx>
7fd59977 29#include <LocOpe_GluedShape.hxx>
42cf5bc1 30#include <LocOpe_Gluer.hxx>
31#include <LocOpe_Spliter.hxx>
7fd59977 32#include <LocOpe_WiresOnShape.hxx>
42cf5bc1 33#include <Precision.hxx>
34#include <Standard_ConstructionError.hxx>
35#include <Standard_NoSuchObject.hxx>
36#include <StdFail_NotDone.hxx>
7fd59977 37#include <TopExp.hxx>
42cf5bc1 38#include <TopExp_Explorer.hxx>
39#include <TopoDS.hxx>
40#include <TopoDS_Edge.hxx>
41#include <TopoDS_Face.hxx>
42#include <TopoDS_Shape.hxx>
43#include <TopoDS_Vertex.hxx>
7fd59977 44#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
45#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
7fd59977 46#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47#include <TopTools_IndexedMapOfShape.hxx>
42cf5bc1 48#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 49
50static TopAbs_Orientation GetOrientation(const TopoDS_Face&,
51 const TopoDS_Face&);
52
53
54static Standard_Boolean Contains(const TopTools_ListOfShape&,
55 const TopoDS_Shape&);
56
57
58//=======================================================================
59//function : Init
60//purpose :
61//=======================================================================
62
63void LocOpe_Gluer::Init(const TopoDS_Shape& Sbase,
64 const TopoDS_Shape& Snew)
65{
66 mySb = Sbase;
67 mySn = Snew;
68 myMapEF.Clear();
69 myMapEE.Clear();
70 myDescF.Clear();
71 myDone = Standard_False;
72 myOri = TopAbs_INTERNAL;
73 myOpe = LocOpe_INVALID;
74}
75
76
77//=======================================================================
78//function : Bind
79//purpose :
80//=======================================================================
81
82void LocOpe_Gluer::Bind(const TopoDS_Face& Fnew,
83 const TopoDS_Face& Fbase)
84{
85 TopExp_Explorer exp(mySn,TopAbs_FACE);
86
87 for (; exp.More(); exp.Next()) {
88 if (exp.Current().IsSame(Fnew)) {
89 break;
90 }
91 }
92 if (!exp.More()) {
9775fa61 93 throw Standard_ConstructionError();
7fd59977 94 }
95
96 TopoDS_Shape aLocalFace = Fnew.Oriented(exp.Current().Orientation());
97 TopoDS_Face Fnor = TopoDS::Face(aLocalFace);
98// TopoDS_Face Fnor = TopoDS::Face(Fnew.Oriented(exp.Current().Orientation()));
99
100 for (exp.Init(mySb,TopAbs_FACE); exp.More(); exp.Next()) {
101 if (exp.Current().IsSame(Fbase)) {
102 break;
103 }
104 }
105 if (!exp.More()) {
9775fa61 106 throw Standard_ConstructionError();
7fd59977 107 }
108
109 aLocalFace = Fbase.Oriented(exp.Current().Orientation());
110 TopoDS_Face Fbor = TopoDS::Face(aLocalFace);
111// TopoDS_Face Fbor = TopoDS::Face(Fbase.Oriented(exp.Current().Orientation()));
112 TopAbs_Orientation Ori = GetOrientation(Fnor,Fbor);
113
114 if (myOri == TopAbs_INTERNAL) {
115 myOri = Ori;
116 if (myOri == TopAbs_REVERSED) {
117 mySn.Reverse();
118 myOpe = LocOpe_CUT;
119 }
120 else {
121 myOpe = LocOpe_FUSE;
122 }
123 }
124 else if (Ori != TopAbs_FORWARD) {
125 myOpe = LocOpe_INVALID;
126 }
127
128 for (exp.Init(Fnor, TopAbs_EDGE); exp.More(); exp.Next()) {
129 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
130// if (!myMapEF.IsBound(edg)) {
131// myMapEF.Bind(edg,Fbor);
132 if (!myMapEF.Contains(edg)) {
133 myMapEF.Add(edg,Fbor);
134 }
135// else if (!myMapEF(edg).IsSame(Fbor)) {
136 else if (!myMapEF.FindFromKey(edg).IsSame(Fbor)) {
137// myMapEF.UnBind(edg); // edg sur 2 face. a binder avec l`edge commun
138 myMapEF.ChangeFromKey(edg).Nullify();
139 // edg sur 2 face. a binder avec l`edge commun
140 }
141 }
142// myMapEF.Bind(Fnor,Fbor);
143 myMapEF.Add(Fnor,Fbor);
144}
145
146
147//=======================================================================
148//function : Bind
149//purpose :
150//=======================================================================
151
152void LocOpe_Gluer::Bind(const TopoDS_Edge& Enew,
153 const TopoDS_Edge& Ebase)
154{
155 if (myMapEE.IsBound(Enew) && !myMapEE(Enew).IsSame(Ebase)) {
9775fa61 156 throw Standard_ConstructionError();
7fd59977 157 }
158 myMapEE.Bind(Enew,Ebase);
159}
160
161
162//=======================================================================
163//function : Perform
164//purpose :
165//=======================================================================
166
167void LocOpe_Gluer::Perform()
168{
169 Standard_Integer ind ;
170 if (myDone) {
171 return;
172 }
173 if (mySb.IsNull() || mySn.IsNull() ||
174 myMapEF.IsEmpty() || myOpe ==LocOpe_INVALID) {
9775fa61 175 throw Standard_ConstructionError();
7fd59977 176 }
177
178 Handle(LocOpe_WiresOnShape) theWOnS = new LocOpe_WiresOnShape(mySb);
179 Handle(LocOpe_GluedShape) theGS = new LocOpe_GluedShape(mySn);
180
181 Standard_Integer lmap = myMapEF.Extent();
182
183 for ( ind = 1; ind <= lmap; ind++) {
184 TopoDS_Shape S = myMapEF.FindKey(ind);
185 if (S.ShapeType() == TopAbs_EDGE) {
186 TopoDS_Shape S2 = myMapEF(ind);
187 if (!S2.IsNull()) {
188 theWOnS->Bind(TopoDS::Edge(S), TopoDS::Face(S2));
189 }
190 }
191 else { // TopAbs_FACE
192 theGS->GlueOnFace(TopoDS::Face(S));
193 }
194 }
195
196 TopTools_DataMapIteratorOfDataMapOfShapeShape itm(myMapEE);
197 for (; itm.More(); itm.Next()) {
198 theWOnS->Bind(TopoDS::Edge(itm.Key()), TopoDS::Edge(itm.Value()));
199 }
200
201 theWOnS->BindAll();
202
203 if (!theWOnS->IsDone()) {
204 return;
205 }
206
207 LocOpe_Spliter theSplit(mySb);
208 theSplit.Perform(theWOnS);
209 if (!theSplit.IsDone()) {
210 return;
211 }
212 // Mise a jour des descendants
213// for (TopExp_Explorer exp(mySb,TopAbs_FACE); exp.More(); exp.Next()) {
214 TopExp_Explorer exp(mySb,TopAbs_FACE) ;
215 for ( ; exp.More(); exp.Next()) {
216 myDescF.Bind(exp.Current(),theSplit.DescendantShapes(exp.Current()));
217 }
218
219 for (exp.Init(mySn,TopAbs_FACE); exp.More(); exp.Next()) {
220 TopTools_ListOfShape thelist;
221 myDescF.Bind(exp.Current(), thelist);
222 if (Contains(theGS->OrientedFaces(),exp.Current())) {
223 myDescF(exp.Current()).Append(exp.Current());
224 }
225 }
226
227 LocOpe_Generator theGen(theSplit.ResultingShape());
228 theGen.Perform(theGS);
229
230 myDone = theGen.IsDone();
231 if (myDone) {
232 myRes = theGen.ResultingShape();
233
234 AddEdges();
235
236 // Mise a jour des descendants
237 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itd;
238 for (itd.Initialize(myDescF);
239 itd.More();
240 itd.Next()) {
241 TopTools_ListOfShape newDesc;
242 TopTools_ListIteratorOfListOfShape itl;
243 for (itl.Initialize(itd.Value());
244 itl.More();
245 itl.Next()) {
246 TopTools_ListIteratorOfListOfShape itl2
247 (theGen.DescendantFace(TopoDS::Face(itl.Value())));
248 for (; itl2.More(); itl2.Next()) {
249 const TopoDS_Face& descface =TopoDS::Face(itl2.Value());
250 if (!descface.IsNull()) { // sinon la face a disparu
251 newDesc.Append(descface);
252 }
253 }
254 }
255 myDescF(itd.Key()) = newDesc;
256 }
257 }
258
259 // recodage des regularites
260 TopTools_IndexedDataMapOfShapeListOfShape theMapEF1, theMapEF2;
261 TopExp::MapShapesAndAncestors(mySn,TopAbs_EDGE,TopAbs_FACE,theMapEF1);
262 TopExp::MapShapesAndAncestors(myRes,TopAbs_EDGE,TopAbs_FACE,theMapEF2);
263
264 for (ind = 1; ind <= theMapEF1.Extent(); ind++) {
265 const TopoDS_Edge& edg = TopoDS::Edge(theMapEF1.FindKey(ind));
266 const TopTools_ListOfShape& LL = theMapEF1(ind);
267 if (LL.Extent() == 2) {
268 const TopoDS_Face& fac1 = TopoDS::Face(LL.First());
269 const TopoDS_Face& fac2 = TopoDS::Face(LL.Last());
270 GeomAbs_Shape thecont = BRep_Tool::Continuity(edg,fac1,fac2);
271 if (thecont >= GeomAbs_G1) {
272 // on essaie de recoder
273 Standard_Integer ind2 = theMapEF2.FindIndex(edg);
274 if (ind2 != 0) {
275 const TopTools_ListOfShape& LL2 = theMapEF2(ind2);
276 if (LL2.Extent() == 2) {
277 const TopoDS_Face& ff1 = TopoDS::Face(LL2.First());
278 const TopoDS_Face& ff2 = TopoDS::Face(LL2.Last());
279 if ((ff1.IsSame(fac1) && ff2.IsSame(fac2)) ||
280 (ff1.IsSame(fac2) && ff2.IsSame(fac1))) {
281
282 }
283 else {
284 BRep_Builder B;
285 B.Continuity(edg, ff1,ff2,thecont);
286 }
287 }
288 }
289 }
290 }
291 }
292 //creation de la liste d`edge
293 theWOnS->InitEdgeIterator();
294 while(theWOnS->MoreEdge()) {
295 TopoDS_Edge edg = theWOnS->Edge();
296 for (ind = 1; ind <= theMapEF2.Extent(); ind++) {
297 const TopoDS_Edge& edg1 = TopoDS::Edge(theMapEF2.FindKey(ind));
298 if(edg1.IsSame(edg)) {
299 myEdges.Append(edg);
300 // recodage eventuel des regularites sur cet edge
301 const TopTools_ListOfShape& L = theMapEF2(ind);
302 if (L.Extent() == 2) {
303 const TopoDS_Face& fac1 = TopoDS::Face(L.First());
304 const TopoDS_Face& fac2 = TopoDS::Face(L.Last());
305 if(LocOpe::TgtFaces(edg, fac1, fac2)) {
306 myTgtEdges.Append(edg);
307 GeomAbs_Shape thecont = BRep_Tool::Continuity(edg,fac1,fac2);
308 if (thecont < GeomAbs_G1) {
309 BRep_Builder B;
310 B.Continuity(edg, fac1,fac2,GeomAbs_G1);
311 }
312 }
313 }
314 }
315 }
316 theWOnS->NextEdge();
317 }
318
319 // recodage eventuel des regularites sur cet edge
320}
321
322
323
324
325//=======================================================================
326//function : DescendantFaces
327//purpose :
328//=======================================================================
329
330const TopTools_ListOfShape& LocOpe_Gluer::DescendantFaces
331 (const TopoDS_Face& F) const
332{
9775fa61 333 if (!myDone) {throw StdFail_NotDone();}
7fd59977 334 if (myDescF.IsBound(F))
335 return myDescF(F);
336 static TopTools_ListOfShape nullList;
337 return nullList;
338}
339
340
341
342//=======================================================================
343//function : GetOrientation
344//purpose :
345//=======================================================================
346
347static TopAbs_Orientation GetOrientation(const TopoDS_Face& Fn,
348 const TopoDS_Face& Fb)
349{
350
351 Handle(Geom_Surface) Sn,Sb;
352 Sn = BRep_Tool::Surface(Fn);
353 Sb = BRep_Tool::Surface(Fb);
354
355
356 // Find a point on Sb
357 TopExp_Explorer exp;
358 Standard_Real f,l;
359 gp_Pnt2d ptvtx;
360 gp_Pnt pvt;
361 gp_Vec d1u,d1v, n1,n2;
362
363
364 for (exp.Init(Fn,TopAbs_EDGE); exp.More(); exp.Next()) {
365 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
366 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,Fn,f,l);
367 if (Precision::IsNegativeInfinite(f) &&
368 Precision::IsPositiveInfinite(l)) {
369 f = -100.;
370 l = 100.;
371 }
372 else if (Precision::IsNegativeInfinite(f)) {
373 f = l-200.;
374 }
375 else if (Precision::IsPositiveInfinite(l)) {
376 l = f+200.;
377 }
378 Standard_Real deltau = (l-f)/20.;
379 for (Standard_Integer i=1; i<=21; i++) {
380 C2d->D0(f+(i-1)*deltau,ptvtx);
381 Sn->D1(ptvtx.X(),ptvtx.Y(),pvt,d1u,d1v);
382 n1 = d1u.Crossed(d1v);
383 if (n1.Magnitude() > Precision::Confusion() ) {
384 n1.Normalize();
385 if (Fn.Orientation() == TopAbs_REVERSED) {
386 n1.Reverse();
387 }
388
389 // Projection sur Sb
390 GeomAdaptor_Surface GAS(Sb);
391 Standard_Real TolU = GAS.UResolution(Precision::Confusion());
392 Standard_Real TolV = GAS.VResolution(Precision::Confusion());
393 Extrema_ExtPS dist(pvt,GAS,TolU,TolV);
394 if (dist.IsDone()) {
395 Standard_Real dist2min = RealLast();
396 Standard_Integer jmin = 0;
397 for (Standard_Integer j=1; j<=dist.NbExt(); j++) {
398 if (dist.SquareDistance(j)<dist2min) {
399 jmin = j;
400 dist2min = dist.SquareDistance(j);
401 }
402 }
403 if (jmin != 0) {
404 Standard_Real uu,vv;
405 dist.Point(jmin).Parameter(uu,vv);
406 Sb->D1(uu,vv,pvt,d1u,d1v);
407 n2 = d1u.Crossed(d1v);
408 if (n2.Magnitude() > Precision::Confusion()) {
409 n2.Normalize();
410 if (Fb.Orientation() == TopAbs_REVERSED) {
411 n2.Reverse();
412 }
413 if (n1.Dot(n2) > 0.) {
414 return TopAbs_REVERSED;
415 }
416 return TopAbs_FORWARD;
417 }
418 }
419 }
420 }
421 }
422 }
423 return TopAbs_INTERNAL;
424}
425
426
427//=======================================================================
428//function : GetOrientation
429//purpose :
430//=======================================================================
431
432static Standard_Boolean Contains(const TopTools_ListOfShape& L,
433 const TopoDS_Shape& S)
434{
435 TopTools_ListIteratorOfListOfShape it;
436 for (it.Initialize(L);
437 it.More();
438 it.Next()) {
439 if (it.Value().IsSame(S)) {
440 return Standard_True;
441 }
442 }
443 return Standard_False;
444}
445
446
447
448
449
450//=======================================================================
451//function : AddEdges
452//purpose :
453//=======================================================================
454
455void LocOpe_Gluer::AddEdges()
456{
457 TopExp_Explorer exp, expsb;
458 exp.Init(mySn, TopAbs_EDGE);
459
460 TopLoc_Location Loc;
461// Standard_Real l, f;
462 TopTools_IndexedMapOfShape MapV, MapFPrism, MapE;
463 TopExp_Explorer vexp;
464 Standard_Integer flag, i;
465
466 TopExp::MapShapes(mySn, TopAbs_FACE, MapFPrism);
467
468 for (expsb.Init(myRes, TopAbs_FACE); expsb.More(); expsb.Next()) {
469 if (!MapFPrism.Contains(expsb.Current())) {
470 MapV.Clear();
471 TopExp::MapShapes(expsb.Current(), TopAbs_VERTEX, MapV);
472 TopExp::MapShapes(expsb.Current(), TopAbs_EDGE, MapE);
473 for(exp.Init(mySn, TopAbs_EDGE); exp.More(); exp.Next()) {
474 TopoDS_Edge e = TopoDS::Edge(exp.Current());
475 if (MapE.Contains(e)) continue;
476 flag = 0;
477 vexp.Init(e, TopAbs_VERTEX);
478 for(; vexp.More(); vexp.Next()) {
479 TopoDS_Vertex v = TopoDS::Vertex(vexp.Current());
480 if (MapV.Contains(v)) {
481 flag = 1;
482 }
483 }
484 if (flag == 1) {
485
486 vexp.Init(e, TopAbs_VERTEX);
487 BRepExtrema_ExtPF ext;
488 ext.Initialize(TopoDS::Face(expsb.Current()));
489 flag = 0;
490 for(; vexp.More(); vexp.Next()) {
491 TopoDS_Vertex v = TopoDS::Vertex(vexp.Current());
492 if (!MapV.Contains(v)) {
493 ext.Perform(v, TopoDS::Face(expsb.Current()));
494 if (!ext.IsDone() || ext.NbExt() == 0) { flag = 0; break;}
495 else {
496 Standard_Real dist2min = ext.SquareDistance(1);
497 for (i = 2; i <= ext.NbExt(); i++) {
498 dist2min = Min(dist2min, ext.SquareDistance(i));
499 }
500 if (dist2min >= BRep_Tool::Tolerance(v) * BRep_Tool::Tolerance(v)) {
501 flag = 0;
502 break;
503 }
504 else flag = 1;
505 }
506 }
507 else flag = 1;
508 }
509 if (flag == 1) {
510
511 }
512 }
513 }
514 }
515 }
516
517
518}
519