0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / Graphic3d / Graphic3d_Structure.cxx
CommitLineData
b311480e 1// Created by: NW,JPB,CAL
2// Copyright (c) 1991-1999 Matra Datavision
973c2be1 3// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
2831708b 16#include <Graphic3d_Structure.hxx>
7fd59977 17
42cf5bc1 18#include <Bnd_Box.hxx>
19#include <gp_Pnt.hxx>
42cf5bc1 20#include <Graphic3d_DataStructureManager.hxx>
7fd59977 21#include <Graphic3d_GraphicDriver.hxx>
42cf5bc1 22#include <Graphic3d_Group.hxx>
7fd59977 23#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
42cf5bc1 24#include <Graphic3d_MapOfStructure.hxx>
42cf5bc1 25#include <Graphic3d_PriorityDefinitionError.hxx>
42cf5bc1 26#include <Graphic3d_StructureDefinitionError.hxx>
27#include <Graphic3d_StructureManager.hxx>
42cf5bc1 28#include <Graphic3d_TransformError.hxx>
7fd59977 29#include <Quantity_Color.hxx>
7fd59977 30
2831708b 31#include "Graphic3d_Structure.pxx"
32
bc73b006 33#include <Standard_Dump.hxx>
34
63bcc448 35#include <stdio.h>
2831708b 36
25e59720 37IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Structure,Standard_Transient)
92efcf78 38
63bcc448 39//=============================================================================
40//function : Graphic3d_Structure
41//purpose :
42//=============================================================================
679ecdee 43Graphic3d_Structure::Graphic3d_Structure (const Handle(Graphic3d_StructureManager)& theManager,
7dd7c146 44 const Handle(Graphic3d_Structure)& theLinkPrs)
45: myStructureManager(theManager.get()),
46 myOwner (NULL),
47 myVisual (Graphic3d_TOS_ALL),
48 myComputeVisual (Graphic3d_TOS_ALL)
679ecdee 49{
7dd7c146 50 if (!theLinkPrs.IsNull())
51 {
52 myOwner = theLinkPrs->myOwner;
53 myVisual = theLinkPrs->myVisual;
54 myComputeVisual = theLinkPrs->myComputeVisual;
55 myCStructure = theLinkPrs->myCStructure->ShadowLink (theManager);
56 }
57 else
58 {
59 myCStructure = theManager->GraphicDriver()->CreateStructure (theManager);
60 }
679ecdee 61}
62
63//=============================================================================
e6f550da 64//function : ~Graphic3d_Structure
63bcc448 65//purpose :
66//=============================================================================
e6f550da 67Graphic3d_Structure::~Graphic3d_Structure()
63bcc448 68{
b4fd9d00 69 // as myStructureManager can be already destroyed,
bbf32d01 70 // avoid attempts to access it
b4fd9d00 71 myStructureManager = NULL;
63bcc448 72 Remove();
7fd59977 73}
74
63bcc448 75//=============================================================================
dad7fede 76//function : clear
63bcc448 77//purpose :
78//=============================================================================
dad7fede 79void Graphic3d_Structure::clear (const Standard_Boolean theWithDestruction)
98178592
A
80{
81 if (IsDeleted()) return;
7fd59977 82
98178592 83 // clean groups in graphics driver at first
63bcc448 84 GraphicClear (theWithDestruction);
7fd59977 85
b64d84be 86 myCStructure->ContainsFacet = 0;
63bcc448 87 myStructureManager->Clear (this, theWithDestruction);
7fd59977 88
50d06d8f 89 Update (true);
7fd59977 90}
91
b7cd4ba7 92//=======================================================================
93//function : CalculateBoundBox
94//purpose : Calculates AABB of a structure.
95//=======================================================================
96void Graphic3d_Structure::CalculateBoundBox()
97{
7c3ef2f7 98 Graphic3d_BndBox3d aBox;
b7cd4ba7 99 addTransformed (aBox, Standard_True);
7c3ef2f7 100 myCStructure->ChangeBoundingBox() = aBox;
b7cd4ba7 101}
102
63bcc448 103//=============================================================================
104//function : Remove
105//purpose :
106//=============================================================================
107void Graphic3d_Structure::Remove()
108{
109 if (IsDeleted()) return;
98178592 110
6c8126b5
A
111 // clean groups in graphics driver at first; this is also should be done
112 // to avoid unwanted group cleaning in group's destructor
113 // Pass Standard_False to Clear(..) method to avoid updating in
114 // structure manager, it isn't necessary, besides of it structure manager
115 // could be already destroyed and invalid pointers used in structure;
b64d84be 116 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
117 {
118 aGroupIter.ChangeValue()->Clear (Standard_False);
119 }
98178592 120
7dd7c146 121 // It is necessary to remove the eventual pointer on the structure that can be destroyed, in the list of descendants
122 // of ancestors of this structure and in the list of ancestors of descendants of the same structure.
602d1ead 123 for (Standard_Integer aStructIdx = 1, aNbDesc = myDescendants.Size(); aStructIdx <= aNbDesc; ++aStructIdx)
63bcc448 124 {
7dd7c146 125 myDescendants.FindKey (aStructIdx)->Remove (this, Graphic3d_TOC_ANCESTOR);
63bcc448 126 }
7fd59977 127
602d1ead 128 for (Standard_Integer aStructIdx = 1, aNbAnces = myAncestors.Size(); aStructIdx <= aNbAnces; ++aStructIdx)
63bcc448 129 {
7dd7c146 130 myAncestors.FindKey (aStructIdx)->Remove (this, Graphic3d_TOC_DESCENDANT);
63bcc448 131 }
7fd59977 132
81bba717 133 // Destruction of me in the graphic library
63bcc448 134 const Standard_Integer aStructId = myCStructure->Id;
016e5959 135 myCStructure->GraphicDriver()->RemoveIdentification(aStructId);
63bcc448 136 myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
137 myCStructure.Nullify();
7fd59977 138}
139
63bcc448 140//=============================================================================
141//function : Display
142//purpose :
143//=============================================================================
144void Graphic3d_Structure::Display()
145{
146 if (IsDeleted()) return;
7fd59977 147
63bcc448 148 if (!myCStructure->stick)
149 {
150 myCStructure->stick = 1;
151 myStructureManager->Display (this);
7fd59977 152 }
153
a1954302 154 if (myCStructure->visible != 1)
155 {
156 myCStructure->visible = 1;
157 myCStructure->OnVisibilityChanged();
158 }
7fd59977 159}
160
63bcc448 161//=============================================================================
63bcc448 162//function : SetDisplayPriority
163//purpose :
164//=============================================================================
165void Graphic3d_Structure::SetDisplayPriority (const Standard_Integer thePriority)
166{
167 if (IsDeleted()
168 || thePriority == myCStructure->Priority)
169 {
170 return;
171 }
7fd59977 172
63bcc448 173 myCStructure->PreviousPriority = myCStructure->Priority;
174 myCStructure->Priority = thePriority;
7fd59977 175
63bcc448 176 if (myCStructure->Priority != myCStructure->PreviousPriority)
177 {
178 Graphic3d_PriorityDefinitionError_Raise_if ((myCStructure->Priority > Structure_MAX_PRIORITY)
179 || (myCStructure->Priority < Structure_MIN_PRIORITY),
180 "Bad value for StructurePriority");
181 if (myCStructure->stick)
182 {
183 myStructureManager->ChangeDisplayPriority (this, myCStructure->PreviousPriority, myCStructure->Priority);
184 }
7fd59977 185 }
7fd59977 186}
187
63bcc448 188//=============================================================================
189//function : ResetDisplayPriority
190//purpose :
191//=============================================================================
192void Graphic3d_Structure::ResetDisplayPriority()
193{
194 if (IsDeleted()
195 || myCStructure->Priority == myCStructure->PreviousPriority)
196 {
197 return;
7fd59977 198 }
199
63bcc448 200 const Standard_Integer aPriority = myCStructure->Priority;
201 myCStructure->Priority = myCStructure->PreviousPriority;
202 if (myCStructure->stick)
203 {
204 myStructureManager->ChangeDisplayPriority (this, aPriority, myCStructure->Priority);
205 }
7fd59977 206}
7fd59977 207
63bcc448 208//=============================================================================
dad7fede 209//function : erase
63bcc448 210//purpose :
211//=============================================================================
dad7fede 212void Graphic3d_Structure::erase()
63bcc448 213{
214 if (IsDeleted())
215 {
216 return;
7fd59977 217 }
218
63bcc448 219 if (myCStructure->stick)
220 {
221 myCStructure->stick = 0;
222 myStructureManager->Erase (this);
223 }
7fd59977 224}
225
63bcc448 226//=============================================================================
227//function : Highlight
228//purpose :
229//=============================================================================
f838dac4 230void Graphic3d_Structure::Highlight (const Handle(Graphic3d_PresentationAttributes)& theStyle,
231 const Standard_Boolean theToUpdateMgr)
63bcc448 232{
233 if (IsDeleted())
234 {
235 return;
236 }
7fd59977 237
63bcc448 238 SetDisplayPriority (Structure_MAX_PRIORITY - 1);
7fd59977 239
98b15dbf 240 myCStructure->GraphicHighlight (theStyle);
7fd59977 241
a1954302 242 if (!theToUpdateMgr)
63bcc448 243 {
244 return;
245 }
7fd59977 246
a1954302 247 if (myCStructure->stick)
63bcc448 248 {
8e5fb5ea 249 myStructureManager->Highlight (this);
7fd59977 250 }
251
a1954302 252 Update();
7fd59977 253}
254
63bcc448 255//=============================================================================
256//function : SetVisible
257//purpose :
258//=============================================================================
259void Graphic3d_Structure::SetVisible (const Standard_Boolean theValue)
260{
261 if (IsDeleted()) return;
7fd59977 262
a1954302 263 const unsigned isVisible = theValue ? 1 : 0;
264 if (myCStructure->visible == isVisible)
63bcc448 265 {
a1954302 266 return;
63bcc448 267 }
a1954302 268
269 myCStructure->visible = isVisible;
270 myCStructure->OnVisibilityChanged();
50d06d8f 271 Update (true);
7fd59977 272}
273
63bcc448 274//=============================================================================
275//function : UnHighlight
276//purpose :
277//=============================================================================
278void Graphic3d_Structure::UnHighlight()
279{
280 if (IsDeleted()) return;
7fd59977 281
63bcc448 282 if (myCStructure->highlight)
283 {
284 myCStructure->highlight = 0;
7fd59977 285
8e5fb5ea 286 myCStructure->GraphicUnhighlight();
63bcc448 287 myStructureManager->UnHighlight (this);
7fd59977 288
7fd59977 289 ResetDisplayPriority();
63bcc448 290 Update();
7fd59977 291 }
7fd59977 292}
293
63bcc448 294//=============================================================================
63bcc448 295//function : ContainsFacet
296//purpose :
297//=============================================================================
298Standard_Boolean Graphic3d_Structure::ContainsFacet() const
299{
300 if (IsDeleted())
301 {
302 return Standard_False;
303 }
304 else if (myCStructure->ContainsFacet > 0)
305 {
306 // if one of groups contains at least one facet, the structure contains it too
307 return Standard_True;
308 }
7fd59977 309
63bcc448 310 // stop at the first descendant containing at least one facet
7dd7c146 311 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
63bcc448 312 {
7dd7c146 313 if (anIter.Value()->ContainsFacet())
63bcc448 314 {
315 return Standard_True;
316 }
317 }
318 return Standard_False;
7fd59977 319}
320
63bcc448 321//=============================================================================
322//function : IsEmpty
323//purpose :
324//=============================================================================
325Standard_Boolean Graphic3d_Structure::IsEmpty() const
326{
327 if (IsDeleted())
328 {
329 return Standard_True;
330 }
7fd59977 331
63bcc448 332 // structure is empty:
333 // - if all these groups are empty
334 // - or if all groups are empty and all their descendants are empty
335 // - or if all its descendants are empty
b64d84be 336 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
63bcc448 337 {
b64d84be 338 if (!aGroupIter.Value()->IsEmpty())
63bcc448 339 {
340 return Standard_False;
341 }
342 }
7fd59977 343
63bcc448 344 // stop at the first non-empty descendant
7dd7c146 345 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
63bcc448 346 {
7dd7c146 347 if (!anIter.Value()->IsEmpty())
63bcc448 348 {
349 return Standard_False;
350 }
351 }
352 return Standard_True;
7fd59977 353}
354
63bcc448 355//=============================================================================
63bcc448 356//function : GroupsWithFacet
357//purpose :
358//=============================================================================
359void Graphic3d_Structure::GroupsWithFacet (const Standard_Integer theDelta)
360{
361 myCStructure->ContainsFacet = myCStructure->ContainsFacet + theDelta;
362 if (myCStructure->ContainsFacet < 0)
363 {
364 myCStructure->ContainsFacet = 0;
365 }
7fd59977 366}
367
63bcc448 368//=============================================================================
63bcc448 369//function : ReCompute
370//purpose :
371//=============================================================================
372void Graphic3d_Structure::ReCompute()
373{
374 myStructureManager->ReCompute (this);
7fd59977 375}
376
63bcc448 377//=============================================================================
378//function : ReCompute
379//purpose :
380//=============================================================================
381void Graphic3d_Structure::ReCompute (const Handle(Graphic3d_DataStructureManager)& theProjector)
382{
383 myStructureManager->ReCompute (this, theProjector);
7fd59977 384}
385
197ac94e 386//=============================================================================
63bcc448 387//function : GraphicClear
388//purpose :
389//=============================================================================
390void Graphic3d_Structure::GraphicClear (const Standard_Boolean theWithDestruction)
5e27df78 391{
b64d84be 392 if (myCStructure.IsNull())
5e27df78 393 {
b64d84be 394 return;
5e27df78 395 }
7fd59977 396
b64d84be 397 // clean and empty each group
398 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
5e27df78 399 {
b64d84be 400 aGroupIter.ChangeValue()->Clear();
401 }
402 if (!theWithDestruction)
403 {
404 return;
405 }
7fd59977 406
b64d84be 407 while (!myCStructure->Groups().IsEmpty())
408 {
409 Handle(Graphic3d_Group) aGroup = myCStructure->Groups().First();
410 aGroup->Remove();
7fd59977 411 }
b64d84be 412 myCStructure->Clear();
7fd59977 413}
414
63bcc448 415//=============================================================================
63bcc448 416//function : SetVisual
417//purpose :
418//=============================================================================
419void Graphic3d_Structure::SetVisual (const Graphic3d_TypeOfStructure theVisual)
420{
421 if (IsDeleted()
422 || myVisual == theVisual)
423 {
424 return;
7fd59977 425 }
7fd59977 426
63bcc448 427 if (!myCStructure->stick)
428 {
429 myVisual = theVisual;
430 SetComputeVisual (theVisual);
431 }
432 else
433 {
dad7fede 434 erase();
cfece3ef 435 myVisual = theVisual;
436 SetComputeVisual (theVisual);
437 Display();
7fd59977 438 }
7fd59977 439}
440
63bcc448 441//=============================================================================
442//function : SetZoomLimit
443//purpose :
444//=============================================================================
445void Graphic3d_Structure::SetZoomLimit (const Standard_Real theLimitInf,
446 const Standard_Real theLimitSup)
447{
448 (void )theLimitInf;
449 (void )theLimitSup;
450 Graphic3d_StructureDefinitionError_Raise_if (theLimitInf <= 0.0,
451 "Bad value for ZoomLimit inf");
452 Graphic3d_StructureDefinitionError_Raise_if (theLimitSup <= 0.0,
453 "Bad value for ZoomLimit sup");
454 Graphic3d_StructureDefinitionError_Raise_if (theLimitSup < theLimitInf,
455 "ZoomLimit sup < ZoomLimit inf");
7fd59977 456}
457
63bcc448 458//=============================================================================
63bcc448 459//function : AcceptConnection
460//purpose :
461//=============================================================================
7dd7c146 462Standard_Boolean Graphic3d_Structure::AcceptConnection (Graphic3d_Structure* theStructure1,
463 Graphic3d_Structure* theStructure2,
464 Graphic3d_TypeOfConnection theType)
63bcc448 465{
7fd59977 466 // cycle detection
7dd7c146 467 NCollection_Map<Graphic3d_Structure*> aSet;
63bcc448 468 Graphic3d_Structure::Network (theStructure2, theType, aSet);
469 return !aSet.Contains (theStructure1);
7fd59977 470}
471
63bcc448 472//=============================================================================
473//function : Ancestors
474//purpose :
475//=============================================================================
476void Graphic3d_Structure::Ancestors (Graphic3d_MapOfStructure& theSet) const
477{
7dd7c146 478 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myAncestors); anIter.More(); anIter.Next())
63bcc448 479 {
7dd7c146 480 theSet.Add (anIter.Value());
63bcc448 481 }
7fd59977 482}
483
63bcc448 484//=============================================================================
63bcc448 485//function : Descendants
486//purpose :
487//=============================================================================
488void Graphic3d_Structure::Descendants (Graphic3d_MapOfStructure& theSet) const
489{
7dd7c146 490 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
63bcc448 491 {
7dd7c146 492 theSet.Add (anIter.Value());
63bcc448 493 }
7fd59977 494}
495
63bcc448 496//=============================================================================
602d1ead 497//function : AppendAncestor
d4aaad5b 498//purpose :
499//=============================================================================
7dd7c146 500Standard_Boolean Graphic3d_Structure::AppendAncestor (Graphic3d_Structure* theAncestor)
d4aaad5b 501{
602d1ead 502 const Standard_Integer aSize = myAncestors.Size();
d4aaad5b 503
602d1ead 504 return myAncestors.Add (theAncestor) > aSize; // new object
d4aaad5b 505}
506
507//=============================================================================
602d1ead 508//function : AppendDescendant
d4aaad5b 509//purpose :
510//=============================================================================
7dd7c146 511Standard_Boolean Graphic3d_Structure::AppendDescendant (Graphic3d_Structure* theDescendant)
d4aaad5b 512{
602d1ead 513 const Standard_Integer aSize = myDescendants.Size();
d4aaad5b 514
602d1ead 515 return myDescendants.Add (theDescendant) > aSize; // new object
d4aaad5b 516}
517
518//=============================================================================
602d1ead 519//function : RemoveAncestor
d4aaad5b 520//purpose :
521//=============================================================================
7dd7c146 522Standard_Boolean Graphic3d_Structure::RemoveAncestor (Graphic3d_Structure* theAncestor)
d4aaad5b 523{
602d1ead 524 const Standard_Integer anIndex = myAncestors.FindIndex (theAncestor);
525
526 if (anIndex != 0)
d4aaad5b 527 {
602d1ead 528 myAncestors.Swap (anIndex, myAncestors.Size());
529 myAncestors.RemoveLast();
d4aaad5b 530 }
531
602d1ead 532 return anIndex != 0; // object was found
d4aaad5b 533}
534
535//=============================================================================
602d1ead 536//function : RemoveDescendant
d4aaad5b 537//purpose :
538//=============================================================================
7dd7c146 539Standard_Boolean Graphic3d_Structure::RemoveDescendant (Graphic3d_Structure* theDescendant)
d4aaad5b 540{
602d1ead 541 const Standard_Integer anIndex = myDescendants.FindIndex (theDescendant);
d4aaad5b 542
602d1ead 543 if (anIndex != 0)
d4aaad5b 544 {
602d1ead 545 myDescendants.Swap (anIndex, myDescendants.Size());
546 myDescendants.RemoveLast();
d4aaad5b 547 }
548
602d1ead 549 return anIndex != 0; // object was found
d4aaad5b 550}
551
552//=============================================================================
63bcc448 553//function : Connect
554//purpose :
555//=============================================================================
7dd7c146 556void Graphic3d_Structure::Connect (Graphic3d_Structure* theStructure,
557 Graphic3d_TypeOfConnection theType,
558 Standard_Boolean theWithCheck)
63bcc448 559{
d4aaad5b 560 if (IsDeleted())
561 {
562 return;
563 }
7fd59977 564
63bcc448 565 // cycle detection
566 if (theWithCheck
567 && !Graphic3d_Structure::AcceptConnection (this, theStructure, theType))
7fd59977 568 {
63bcc448 569 return;
570 }
7fd59977 571
d4aaad5b 572 if (theType == Graphic3d_TOC_DESCENDANT)
63bcc448 573 {
7dd7c146 574 if (!AppendDescendant (theStructure))
7fd59977 575 {
d4aaad5b 576 return;
577 }
7fd59977 578
d4aaad5b 579 CalculateBoundBox();
580 theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
7fd59977 581
d4aaad5b 582 GraphicConnect (theStructure);
583 myStructureManager->Connect (this, theStructure);
7fd59977 584
50d06d8f 585 Update (true);
d4aaad5b 586 }
587 else // Graphic3d_TOC_ANCESTOR
588 {
7dd7c146 589 if (!AppendAncestor (theStructure))
d4aaad5b 590 {
63bcc448 591 return;
7fd59977 592 }
63bcc448 593
d4aaad5b 594 CalculateBoundBox();
595 theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
63bcc448 596
d4aaad5b 597 // myStructureManager->Connect is called in case if connection between parent and child
7fd59977 598 }
7fd59977 599}
600
63bcc448 601//=============================================================================
602//function : Disconnect
603//purpose :
604//=============================================================================
7dd7c146 605void Graphic3d_Structure::Disconnect (Graphic3d_Structure* theStructure)
63bcc448 606{
d4aaad5b 607 if (IsDeleted())
63bcc448 608 {
d4aaad5b 609 return;
610 }
7fd59977 611
7dd7c146 612 if (RemoveDescendant (theStructure))
d4aaad5b 613 {
614 theStructure->Disconnect (this);
b7cd4ba7 615
d4aaad5b 616 GraphicDisconnect (theStructure);
617 myStructureManager->Disconnect (this, theStructure);
7fd59977 618
d4aaad5b 619 CalculateBoundBox();
50d06d8f 620 Update (true);
d4aaad5b 621 }
7dd7c146 622 else if (RemoveAncestor (theStructure))
63bcc448 623 {
d4aaad5b 624 theStructure->Disconnect (this);
625 CalculateBoundBox();
626
627 // no call of myStructureManager->Disconnect in case of an ancestor
7fd59977 628 }
7fd59977 629}
630
63bcc448 631//=============================================================================
632//function : DisconnectAll
633//purpose :
634//=============================================================================
635void Graphic3d_Structure::DisconnectAll (const Graphic3d_TypeOfConnection theType)
636{
637 if (IsDeleted()) return;
7fd59977 638
63bcc448 639 switch (theType)
7fd59977 640 {
63bcc448 641 case Graphic3d_TOC_DESCENDANT:
642 {
602d1ead 643 for (Standard_Integer anIdx = 1, aLength = myDescendants.Size(); anIdx <= aLength; ++anIdx)
63bcc448 644 {
645 // Value (1) instead of Value (i) as myDescendants
646 // is modified by :
647 // Graphic3d_Structure::Disconnect (AStructure)
648 // that takes AStructure from myDescendants
7dd7c146 649 myDescendants.FindKey (1)->Disconnect (this);
63bcc448 650 }
651 break;
652 }
653 case Graphic3d_TOC_ANCESTOR:
654 {
602d1ead 655 for (Standard_Integer anIdx = 1, aLength = myAncestors.Size(); anIdx <= aLength; ++anIdx)
63bcc448 656 {
657 // Value (1) instead of Value (i) as myAncestors
658 // is modified by :
659 // Graphic3d_Structure::Disconnect (AStructure)
660 // that takes AStructure from myAncestors
7dd7c146 661 myAncestors.FindKey (1)->Disconnect (this);
63bcc448 662 }
663 break;
664 }
7fd59977 665 }
7fd59977 666}
667
63bcc448 668//=============================================================================
63bcc448 669//function : SetTransform
670//purpose :
671//=============================================================================
7f24b768 672void Graphic3d_Structure::SetTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
63bcc448 673{
674 if (IsDeleted()) return;
7fd59977 675
1f7f5a90 676 const Standard_Boolean wasTransformed = IsTransformed();
677
678 if (!theTrsf.IsNull()
679 && theTrsf->Trsf().Form() == gp_Identity)
63bcc448 680 {
7f24b768 681 myCStructure->SetTransformation (Handle(TopLoc_Datum3D)());
7fd59977 682 }
1f7f5a90 683 else
63bcc448 684 {
1f7f5a90 685 myCStructure->SetTransformation (theTrsf);
7fd59977 686 }
687
63bcc448 688 // If transformation, no validation of hidden already calculated parts
6bd94e0d 689 if (IsTransformed() || (!IsTransformed() && wasTransformed))
63bcc448 690 {
691 ReCompute();
692 }
7fd59977 693
1f7f5a90 694 myStructureManager->SetTransform (this, theTrsf);
7fd59977 695
50d06d8f 696 Update (true);
7fd59977 697}
698
63bcc448 699//=============================================================================
197ac94e 700//function : MinMaxValues
701//purpose :
702//=============================================================================
ed063270 703Bnd_Box Graphic3d_Structure::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
197ac94e 704{
7c3ef2f7 705 Graphic3d_BndBox3d aBox;
b7cd4ba7 706 addTransformed (aBox, theToIgnoreInfiniteFlag);
7c3ef2f7 707 if (!aBox.IsValid())
197ac94e 708 {
7c3ef2f7 709 return Bnd_Box();
710 }
711
712 Bnd_Box aResult;
713 aResult.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
714 aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
715
716 Standard_Real aLimMin = ShortRealFirst() + 1.0;
717 Standard_Real aLimMax = ShortRealLast() - 1.0;
718 gp_Pnt aMin = aResult.CornerMin();
719 gp_Pnt aMax = aResult.CornerMax();
720 if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin
721 && aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
722 {
723 //For structure which infinite in all three dimensions the Whole bounding box will be returned
724 aResult.SetWhole();
197ac94e 725 }
ed063270 726 return aResult;
7fd59977 727}
728
63bcc448 729//=============================================================================
63bcc448 730//function : SetTransformPersistence
731//purpose :
732//=============================================================================
778cd667 733void Graphic3d_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
7fd59977 734{
778cd667 735 if (IsDeleted())
736 {
737 return;
738 }
7fd59977 739
778cd667 740 myCStructure->SetTransformPersistence (theTrsfPers);
7fd59977 741}
742
63bcc448 743//=============================================================================
63bcc448 744//function : Remove
745//purpose :
746//=============================================================================
7dd7c146 747void Graphic3d_Structure::Remove (Graphic3d_Structure* thePtr,
63bcc448 748 const Graphic3d_TypeOfConnection theType)
749{
d4aaad5b 750 if (theType == Graphic3d_TOC_DESCENDANT)
7fd59977 751 {
d4aaad5b 752 RemoveDescendant (thePtr);
753 }
754 else
755 {
756 RemoveAncestor (thePtr);
7fd59977 757 }
7fd59977 758}
759
63bcc448 760//=============================================================================
b64d84be 761//function : NewGroup
762//purpose :
763//=============================================================================
764Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
765{
766 return myCStructure->NewGroup (this);
767}
768
769//=============================================================================
63bcc448 770//function : Remove
771//purpose :
772//=============================================================================
773void Graphic3d_Structure::Remove (const Handle(Graphic3d_Group)& theGroup)
774{
b64d84be 775 if (theGroup.IsNull()
776 || theGroup->myStructure != this)
63bcc448 777 {
b64d84be 778 return;
63bcc448 779 }
b64d84be 780
781 myCStructure->RemoveGroup (theGroup);
782 theGroup->myStructure = NULL;
7fd59977 783}
784
63bcc448 785//=============================================================================
786//function : StructureManager
787//purpose :
788//=============================================================================
789Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
790{
791 return myStructureManager;
7fd59977 792}
793
197ac94e 794//=============================================================================
b7cd4ba7 795//function : minMaxCoord
197ac94e 796//purpose :
797//=============================================================================
8d3aa19e 798Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
197ac94e 799{
b7cd4ba7 800 Graphic3d_BndBox4f aBnd;
b64d84be 801 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
197ac94e 802 {
8d3aa19e 803 aBnd.Combine (aGroupIter.Value()->BoundingBox());
197ac94e 804 }
b7cd4ba7 805 return aBnd;
197ac94e 806}
807
808//=============================================================================
b7cd4ba7 809//function : addTransformed
197ac94e 810//purpose :
811//=============================================================================
7c3ef2f7 812void Graphic3d_Structure::getBox (Graphic3d_BndBox3d& theBox,
0717ddc1 813 const Standard_Boolean theToIgnoreInfiniteFlag) const
197ac94e 814{
8d3aa19e 815 Graphic3d_BndBox4f aBoxF = minMaxCoord();
b7cd4ba7 816 if (aBoxF.IsValid())
197ac94e 817 {
7c3ef2f7 818 theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMin().x(),
0717ddc1 819 (Standard_Real )aBoxF.CornerMin().y(),
7c3ef2f7 820 (Standard_Real )aBoxF.CornerMin().z()),
821 Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMax().x(),
0717ddc1 822 (Standard_Real )aBoxF.CornerMax().y(),
7c3ef2f7 823 (Standard_Real )aBoxF.CornerMax().z()));
b7cd4ba7 824 if (IsInfinite()
825 && !theToIgnoreInfiniteFlag)
197ac94e 826 {
7c3ef2f7 827 const Graphic3d_Vec3d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
828 if (aDiagVec.SquareModulus() >= 500000.0 * 500000.0)
b7cd4ba7 829 {
830 // bounding borders of infinite line has been calculated as own point in center of this line
7c3ef2f7 831 theBox = Graphic3d_BndBox3d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
b7cd4ba7 832 }
833 else
834 {
7c3ef2f7 835 theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d (RealFirst(), RealFirst(), RealFirst()),
836 Graphic3d_Vec3d (RealLast(), RealLast(), RealLast()));
b7cd4ba7 837 return;
838 }
197ac94e 839 }
197ac94e 840 }
0717ddc1 841}
842
843//=============================================================================
844//function : addTransformed
845//purpose :
846//=============================================================================
7c3ef2f7 847void Graphic3d_Structure::addTransformed (Graphic3d_BndBox3d& theBox,
0717ddc1 848 const Standard_Boolean theToIgnoreInfiniteFlag) const
849{
7c3ef2f7 850 Graphic3d_BndBox3d aCombinedBox, aBox;
0717ddc1 851 getBox (aCombinedBox, theToIgnoreInfiniteFlag);
7fd59977 852
7dd7c146 853 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
197ac94e 854 {
7dd7c146 855 const Graphic3d_Structure* aStruct = anIter.Value();
0717ddc1 856 aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
857 aCombinedBox.Combine (aBox);
197ac94e 858 }
7fd59977 859
0717ddc1 860 aBox = aCombinedBox;
b7cd4ba7 861 if (aBox.IsValid())
197ac94e 862 {
1f7f5a90 863 if (!myCStructure->Transformation().IsNull())
864 {
865 TransformBoundaries (myCStructure->Transformation()->Trsf(),
866 aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
867 aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
868 }
0717ddc1 869
870 // if box is still valid after transformation
871 if (aBox.IsValid())
872 {
873 theBox.Combine (aBox);
874 }
875 else // it was infinite, return untransformed
876 {
877 theBox.Combine (aCombinedBox);
878 }
7fd59977 879 }
7fd59977 880}
881
63bcc448 882//=============================================================================
883//function : Transforms
884//purpose :
885//=============================================================================
1f7f5a90 886void Graphic3d_Structure::Transforms (const gp_Trsf& theTrsf,
63bcc448 887 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
888 Standard_Real& theNewX, Standard_Real& theNewY, Standard_Real& theNewZ)
889{
890 const Standard_Real aRL = RealLast();
891 const Standard_Real aRF = RealFirst();
1f7f5a90 892 theNewX = theX;
893 theNewY = theY;
894 theNewZ = theZ;
63bcc448 895 if ((theX == aRF) || (theY == aRF) || (theZ == aRF)
896 || (theX == aRL) || (theY == aRL) || (theZ == aRL))
897 {
1f7f5a90 898 return;
7fd59977 899 }
7fd59977 900
1f7f5a90 901 theTrsf.Transforms (theNewX, theNewY, theNewZ);
7fd59977 902}
903
197ac94e 904//=============================================================================
905//function : Transforms
906//purpose :
907//=============================================================================
1f7f5a90 908void Graphic3d_Structure::TransformBoundaries (const gp_Trsf& theTrsf,
197ac94e 909 Standard_Real& theXMin,
910 Standard_Real& theYMin,
911 Standard_Real& theZMin,
912 Standard_Real& theXMax,
913 Standard_Real& theYMax,
914 Standard_Real& theZMax)
915{
916 Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
917
918 Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
919 Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
920
921 Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
922 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
923 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
924 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
925
926 Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
927 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
928 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
929 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
930
931 Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
932 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
933 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
934 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
935
936 Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
937 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
938 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
939 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
940
941 Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
942 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
943 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
944 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
945
946 Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
947 aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
948 aYMin = Min (aV, aYMin); aYMax = Max (aV, aYMax);
949 aZMin = Min (aW, aZMin); aZMax = Max (aW, aZMax);
950
951 theXMin = aXMin;
952 theYMin = aYMin;
953 theZMin = aZMin;
954 theXMax = aXMax;
955 theYMax = aYMax;
956 theZMax = aZMax;
957}
958
63bcc448 959//=============================================================================
960//function : Network
961//purpose :
962//=============================================================================
7dd7c146 963void Graphic3d_Structure::Network (Graphic3d_Structure* theStructure,
964 const Graphic3d_TypeOfConnection theType,
965 NCollection_Map<Graphic3d_Structure*>& theSet)
63bcc448 966{
63bcc448 967 theSet.Add (theStructure);
968 switch (theType)
7fd59977 969 {
63bcc448 970 case Graphic3d_TOC_DESCENDANT:
7dd7c146 971 {
972 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myDescendants); anIter.More(); anIter.Next())
63bcc448 973 {
7dd7c146 974 Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
63bcc448 975 }
976 break;
7dd7c146 977 }
63bcc448 978 case Graphic3d_TOC_ANCESTOR:
7dd7c146 979 {
980 for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myAncestors); anIter.More(); anIter.Next())
63bcc448 981 {
7dd7c146 982 Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
63bcc448 983 }
984 break;
7dd7c146 985 }
7fd59977 986 }
7fd59977 987}
988
63bcc448 989//=============================================================================
990//function : PrintNetwork
991//purpose :
992//=============================================================================
993void Graphic3d_Structure::PrintNetwork (const Handle(Graphic3d_Structure)& theStructure,
994 const Graphic3d_TypeOfConnection theType)
7fd59977 995{
7dd7c146 996 NCollection_Map<Graphic3d_Structure*> aSet;
997 Graphic3d_Structure::Network (theStructure.get(), theType, aSet);
998 for (NCollection_Map<Graphic3d_Structure*>::Iterator anIter (aSet); anIter.More(); anIter.Next())
63bcc448 999 {
1000 std::cout << "\tIdent " << (anIter.Key())->Identification () << "\n";
7fd59977 1001 }
63bcc448 1002 std::cout << std::flush;
7fd59977 1003}
1004
63bcc448 1005//=============================================================================
1006//function : Update
1007//purpose :
1008//=============================================================================
50d06d8f 1009void Graphic3d_Structure::Update (const bool theUpdateLayer) const
7fd59977 1010{
63bcc448 1011 if (IsDeleted())
1012 {
1013 return;
1014 }
7fd59977 1015
cfece3ef 1016 myStructureManager->Update (theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
63bcc448 1017}
7fd59977 1018
bf75be98 1019//=======================================================================
59f45b7c 1020//function : SetZLayer
1021//purpose :
1022//=======================================================================
a1954302 1023void Graphic3d_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerId)
59f45b7c 1024{
1025 // if the structure is not displayed, unable to change its display layer
1026 if (IsDeleted ())
1027 return;
1028
63bcc448 1029 myStructureManager->ChangeZLayer (this, theLayerId);
a1954302 1030 myCStructure->SetZLayer (theLayerId);
59f45b7c 1031}
bc73b006 1032
1033//=======================================================================
1034//function : DumpJson
1035//purpose :
1036//=======================================================================
1037void Graphic3d_Structure::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1038{
1039 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1040
1041 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myCStructure.get())
1042
1043 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myVisual)
1044 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComputeVisual)
1045}