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