1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <XCAFDoc_ColorTool.hxx>
16 #include <Quantity_Color.hxx>
17 #include <Standard_Dump.hxx>
18 #include <Standard_GUID.hxx>
19 #include <Standard_Type.hxx>
20 #include <TDataStd_Name.hxx>
21 #include <TDataStd_TreeNode.hxx>
22 #include <TDataStd_UAttribute.hxx>
23 #include <TDF_Attribute.hxx>
24 #include <TDF_ChildIDIterator.hxx>
25 #include <TDF_Label.hxx>
26 #include <TDF_RelocationTable.hxx>
27 #include <TNaming_NamedShape.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <XCAFDoc.hxx>
30 #include <XCAFDoc_Color.hxx>
31 #include <XCAFDoc_DocumentTool.hxx>
32 #include <XCAFDoc_GraphNode.hxx>
33 #include <XCAFDoc_ShapeTool.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_ColorTool,TDF_Attribute)
37 static Standard_Boolean XCAFDoc_ColorTool_AutoNaming = Standard_True;
39 //=======================================================================
40 //function : SetAutoNaming
42 //=======================================================================
43 void XCAFDoc_ColorTool::SetAutoNaming (Standard_Boolean theIsAutoNaming)
45 XCAFDoc_ColorTool_AutoNaming = theIsAutoNaming;
48 //=======================================================================
49 //function : AutoNaming
51 //=======================================================================
52 Standard_Boolean XCAFDoc_ColorTool::AutoNaming()
54 return XCAFDoc_ColorTool_AutoNaming;
57 //=======================================================================
58 //function : BaseLabel
60 //=======================================================================
62 TDF_Label XCAFDoc_ColorTool::BaseLabel() const
66 //=======================================================================
67 //function : ShapeTool
69 //=======================================================================
71 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_ColorTool::ShapeTool()
73 if (myShapeTool.IsNull())
74 myShapeTool = XCAFDoc_DocumentTool::ShapeTool(Label());
79 //=======================================================================
82 //=======================================================================
84 Standard_Boolean XCAFDoc_ColorTool::IsColor (const TDF_Label& lab) const
87 return GetColor ( lab, C );
90 //=======================================================================
93 //=======================================================================
95 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& lab,
96 Quantity_Color& col) const
98 Quantity_ColorRGBA aCol;
99 Standard_Boolean isDone = GetColor(lab, aCol);
105 //=======================================================================
106 //function : GetColor
108 //=======================================================================
110 Standard_Boolean XCAFDoc_ColorTool::GetColor(const TDF_Label& lab,
111 Quantity_ColorRGBA& col) const
113 if (lab.Father() != Label()) return Standard_False;
115 Handle(XCAFDoc_Color) ColorAttribute;
116 if (!lab.FindAttribute(XCAFDoc_Color::GetID(), ColorAttribute))
117 return Standard_False;
119 col = ColorAttribute->GetColorRGBA();
121 return Standard_True;
124 //=======================================================================
125 //function : FindColor
127 //=======================================================================
129 Standard_Boolean XCAFDoc_ColorTool::FindColor (const Quantity_Color& col, TDF_Label& lab) const
131 Quantity_ColorRGBA aCol;
133 return FindColor(aCol, lab);
136 //=======================================================================
137 //function : FindColor
139 //=======================================================================
141 Standard_Boolean XCAFDoc_ColorTool::FindColor(const Quantity_ColorRGBA& col, TDF_Label& lab) const
143 TDF_ChildIDIterator it(Label(), XCAFDoc_Color::GetID());
144 for (; it.More(); it.Next()) {
145 TDF_Label aLabel = it.Value()->Label();
146 Quantity_ColorRGBA C;
147 if (!GetColor(aLabel, C)) continue;
148 if (C.IsEqual(col)) {
150 return Standard_True;
153 return Standard_False;
156 //=======================================================================
157 //function : FindColor
159 //=======================================================================
161 TDF_Label XCAFDoc_ColorTool::FindColor (const Quantity_ColorRGBA& col) const
164 FindColor ( col, L );
168 //=======================================================================
169 //function : FindColor
171 //=======================================================================
173 TDF_Label XCAFDoc_ColorTool::FindColor(const Quantity_Color& col) const
180 //=======================================================================
181 //function : AddColor
183 //=======================================================================
185 TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_Color& col) const
187 Quantity_ColorRGBA aCol;
189 return AddColor(aCol);
192 //=======================================================================
193 //function : AddColor
195 //=======================================================================
197 TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_ColorRGBA& theColor) const
200 if (FindColor (theColor, aLab))
205 // create a new color entry
207 aLab = aTag.NewChild (Label());
208 XCAFDoc_Color::Set (aLab, theColor);
210 if (XCAFDoc_ColorTool_AutoNaming)
212 // set name according to color value
213 const NCollection_Vec4<float>& anRgbaF = theColor;
214 const NCollection_Vec4<unsigned int> anRgba (anRgbaF * 255.0f);
216 Sprintf (aColorHex, "%02X%02X%02X%02X", anRgba.r(), anRgba.g(), anRgba.b(), anRgba.a());
217 const TCollection_AsciiString aName = TCollection_AsciiString (Quantity_Color::StringName (theColor.GetRGB().Name()))
218 + " (#" + aColorHex + ")";
219 TDataStd_Name::Set (aLab, aName);
225 //=======================================================================
226 //function : RemoveColor
228 //=======================================================================
230 void XCAFDoc_ColorTool::RemoveColor (const TDF_Label& lab) const
232 lab.ForgetAllAttributes (Standard_True);
235 //=======================================================================
236 //function : GetColors
238 //=======================================================================
240 void XCAFDoc_ColorTool::GetColors (TDF_LabelSequence& Labels) const
244 TDF_ChildIDIterator ChildIDIterator(Label(),XCAFDoc_Color::GetID());
245 for (; ChildIDIterator.More(); ChildIDIterator.Next()) {
246 TDF_Label L = ChildIDIterator.Value()->Label();
247 if ( IsColor ( L ) ) Labels.Append ( L );
251 //=======================================================================
252 //function : SetColor
254 //=======================================================================
256 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
257 const TDF_Label& colorL,
258 const XCAFDoc_ColorType type) const
261 Handle(TDataStd_TreeNode) refNode, mainNode;
262 mainNode = TDataStd_TreeNode::Set ( colorL, XCAFDoc::ColorRefGUID(type) );
263 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ColorRefGUID(type) );
264 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
265 mainNode->Prepend(refNode);
268 //=======================================================================
269 //function : SetColor
271 //=======================================================================
273 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
274 const Quantity_Color& Color,
275 const XCAFDoc_ColorType type) const
277 TDF_Label colorL = AddColor ( Color );
278 SetColor ( L, colorL, type );
281 //=======================================================================
282 //function : SetColor
284 //=======================================================================
286 void XCAFDoc_ColorTool::SetColor(const TDF_Label& L,
287 const Quantity_ColorRGBA& Color,
288 const XCAFDoc_ColorType type) const
290 TDF_Label colorL = AddColor(Color);
291 SetColor(L, colorL, type);
294 //=======================================================================
295 //function : UnSetColor
297 //=======================================================================
299 void XCAFDoc_ColorTool::UnSetColor (const TDF_Label& L, const XCAFDoc_ColorType type) const
301 L.ForgetAttribute ( XCAFDoc::ColorRefGUID(type) );
304 //=======================================================================
307 //=======================================================================
309 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TDF_Label& L, const XCAFDoc_ColorType type) const
311 Handle(TDataStd_TreeNode) Node;
312 return L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) && Node->HasFather();
315 //=======================================================================
316 //function : GetColor
318 //=======================================================================
320 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
321 const XCAFDoc_ColorType type,
324 Handle(TDataStd_TreeNode) Node;
325 if ( ! L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) ||
326 ! Node->HasFather() ) return Standard_False;
327 colorL = Node->Father()->Label();
328 return Standard_True;
331 //=======================================================================
332 //function : GetColor
334 //=======================================================================
336 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
337 const XCAFDoc_ColorType type,
338 Quantity_Color& color)
341 if ( ! GetColor ( L, type, colorL ) ) return Standard_False;
342 return GetColor ( colorL, color );
345 //=======================================================================
346 //function : GetColor
348 //=======================================================================
350 Standard_Boolean XCAFDoc_ColorTool::GetColor(const TDF_Label& L,
351 const XCAFDoc_ColorType type,
352 Quantity_ColorRGBA& color)
355 if (!GetColor(L, type, colorL)) return Standard_False;
356 return GetColor(colorL, color);
359 //=======================================================================
360 //function : SetColor
362 //=======================================================================
364 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
365 const TDF_Label& colorL,
366 const XCAFDoc_ColorType type)
369 if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
370 SetColor ( L, colorL, type );
371 return Standard_True;
374 //=======================================================================
375 //function : SetColor
377 //=======================================================================
379 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
380 const Quantity_Color& Color,
381 const XCAFDoc_ColorType type)
383 TDF_Label colorL = AddColor ( Color );
384 return SetColor ( S, colorL, type );
387 //=======================================================================
388 //function : SetColor
390 //=======================================================================
392 Standard_Boolean XCAFDoc_ColorTool::SetColor(const TopoDS_Shape& S,
393 const Quantity_ColorRGBA& Color,
394 const XCAFDoc_ColorType type)
396 TDF_Label colorL = AddColor(Color);
397 return SetColor(S, colorL, type);
400 //=======================================================================
401 //function : UnSetColor
403 //=======================================================================
405 Standard_Boolean XCAFDoc_ColorTool::UnSetColor (const TopoDS_Shape& S,
406 const XCAFDoc_ColorType type)
409 if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
410 UnSetColor ( L, type );
411 return Standard_True;
414 //=======================================================================
417 //=======================================================================
419 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TopoDS_Shape& S,
420 const XCAFDoc_ColorType type)
423 if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
424 return IsSet ( L, type );
427 //=======================================================================
428 //function : GetColor
430 //=======================================================================
432 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S,
433 const XCAFDoc_ColorType type,
437 if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
438 return GetColor ( L, type, colorL );
441 //=======================================================================
442 //function : GetColor
444 //=======================================================================
446 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S,
447 const XCAFDoc_ColorType type,
448 Quantity_Color& color)
451 if ( ! GetColor ( S, type, colorL ) ) return Standard_False;
452 return GetColor ( colorL, color );
455 //=======================================================================
456 //function : GetColor
458 //=======================================================================
460 Standard_Boolean XCAFDoc_ColorTool::GetColor(const TopoDS_Shape& S,
461 const XCAFDoc_ColorType type,
462 Quantity_ColorRGBA& color)
465 if (!GetColor(S, type, colorL)) return Standard_False;
466 return GetColor(colorL, color);
469 //=======================================================================
472 //=======================================================================
474 const Standard_GUID& XCAFDoc_ColorTool::GetID()
476 static Standard_GUID ColorTblID ("efd212ed-6dfd-11d4-b9c8-0060b0ee281b");
480 //=======================================================================
483 //=======================================================================
485 Handle(XCAFDoc_ColorTool) XCAFDoc_ColorTool::Set(const TDF_Label& L)
487 Handle(XCAFDoc_ColorTool) A;
488 if (!L.FindAttribute (XCAFDoc_ColorTool::GetID(), A)) {
489 A = new XCAFDoc_ColorTool ();
491 A->myShapeTool = XCAFDoc_DocumentTool::ShapeTool(L);
496 //=======================================================================
499 //=======================================================================
501 const Standard_GUID& XCAFDoc_ColorTool::ID() const
506 //=======================================================================
509 //=======================================================================
511 void XCAFDoc_ColorTool::Restore(const Handle(TDF_Attribute)& /*with*/)
515 //=======================================================================
516 //function : NewEmpty
518 //=======================================================================
520 Handle(TDF_Attribute) XCAFDoc_ColorTool::NewEmpty() const
522 return new XCAFDoc_ColorTool;
525 //=======================================================================
528 //=======================================================================
530 void XCAFDoc_ColorTool::Paste (const Handle(TDF_Attribute)& /*into*/,
531 const Handle(TDF_RelocationTable)& /*RT*/) const
537 //=======================================================================
538 //function : XCAFDoc_ColorTool
540 //=======================================================================
542 XCAFDoc_ColorTool::XCAFDoc_ColorTool()
546 // PTV 23.01.2003 add visibility flag for objects (CAX-IF TRJ11)
547 //=======================================================================
548 //function : IsVisible
550 //=======================================================================
552 Standard_Boolean XCAFDoc_ColorTool::IsVisible (const TDF_Label& L) const
554 Handle(TDataStd_UAttribute) aUAttr;
555 return (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr));
558 //=======================================================================
559 //function : SetVisibility
561 //=======================================================================
563 void XCAFDoc_ColorTool::SetVisibility (const TDF_Label& L,
564 const Standard_Boolean isvisible)
566 Handle(TDataStd_UAttribute) aUAttr;
568 Handle(XCAFDoc_GraphNode) aSHUO;
569 if (ShapeTool()->IsShape(L) || ShapeTool()->GetSHUO( L, aSHUO ) )
570 if (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr))
571 TDataStd_UAttribute::Set( L, XCAFDoc::InvisibleGUID() );
573 else L.ForgetAttribute( XCAFDoc::InvisibleGUID() );
576 //=======================================================================
577 //function : IsColorByLayer
579 //=======================================================================
581 Standard_Boolean XCAFDoc_ColorTool::IsColorByLayer (const TDF_Label& L) const
583 Handle(TDataStd_UAttribute) aUAttr;
584 return L.FindAttribute(XCAFDoc::ColorByLayerGUID(), aUAttr);
587 //=======================================================================
588 //function : SetColorByLayer
590 //=======================================================================
592 void XCAFDoc_ColorTool::SetColorByLayer (const TDF_Label& L,
593 const Standard_Boolean isColorByLayer)
595 Handle(TDataStd_UAttribute) aUAttr;
596 if ( isColorByLayer ) {
597 Handle(XCAFDoc_GraphNode) aSHUO;
598 if (ShapeTool()->IsShape(L) || ShapeTool()->GetSHUO( L, aSHUO ) )
599 if (!L.FindAttribute(XCAFDoc::ColorByLayerGUID(), aUAttr))
600 TDataStd_UAttribute::Set( L, XCAFDoc::ColorByLayerGUID() );
602 else L.ForgetAttribute( XCAFDoc::ColorByLayerGUID() );
605 //=======================================================================
606 //function : SetInstanceColor
608 //=======================================================================
610 Standard_Boolean XCAFDoc_ColorTool::SetInstanceColor (const TopoDS_Shape& theShape,
611 const XCAFDoc_ColorType type,
612 const Quantity_Color& color,
613 const Standard_Boolean IsCreateSHUO)
615 Quantity_ColorRGBA aCol;
617 return SetInstanceColor(theShape, type, aCol, IsCreateSHUO);
620 //=======================================================================
621 //function : SetInstanceColor
623 //=======================================================================
625 Standard_Boolean XCAFDoc_ColorTool::SetInstanceColor(const TopoDS_Shape& theShape,
626 const XCAFDoc_ColorType type,
627 const Quantity_ColorRGBA& color,
628 const Standard_Boolean IsCreateSHUO)
630 // find shuo label structure
631 TDF_LabelSequence aLabels;
632 if (!ShapeTool()->FindComponent(theShape, aLabels))
633 return Standard_False;
634 Handle(XCAFDoc_GraphNode) aSHUO;
635 // set the SHUO structure for this component if it is not exist
636 if (!ShapeTool()->FindSHUO(aLabels, aSHUO)) {
637 if (aLabels.Length() == 1) {
638 // set color directly for component as NAUO
639 SetColor(aLabels.Value(1), color, type);
640 return Standard_True;
642 else if (!IsCreateSHUO || !ShapeTool()->SetSHUO(aLabels, aSHUO)) {
643 return Standard_False;
646 TDF_Label aSHUOLabel = aSHUO->Label();
647 SetColor(aSHUOLabel, color, type);
648 return Standard_True;
652 //=======================================================================
653 //function : GetInstanceColor
655 //=======================================================================
657 Standard_Boolean XCAFDoc_ColorTool::GetInstanceColor (const TopoDS_Shape& theShape,
658 const XCAFDoc_ColorType type,
659 Quantity_Color& color)
661 Quantity_ColorRGBA aCol;
662 Standard_Boolean isDone = GetInstanceColor(theShape, type, aCol);
664 color = aCol.GetRGB();
668 //=======================================================================
669 //function : GetInstanceColor
671 //=======================================================================
673 Standard_Boolean XCAFDoc_ColorTool::GetInstanceColor(const TopoDS_Shape& theShape,
674 const XCAFDoc_ColorType type,
675 Quantity_ColorRGBA& color)
677 // find shuo label structure
678 TDF_LabelSequence aLabels;
679 if (!ShapeTool()->FindComponent(theShape, aLabels))
680 return Standard_False;
681 Handle(XCAFDoc_GraphNode) aSHUO;
682 // get shuo from document by label structure
683 TDF_Label aCompLab = aLabels.Value(aLabels.Length());
684 while (aLabels.Length() > 1) {
685 if (!ShapeTool()->FindSHUO(aLabels, aSHUO)) {
686 // try to find other shuo
687 aLabels.Remove(aLabels.Length());
691 TDF_Label aSHUOLabel = aSHUO->Label();
692 if (GetColor(aSHUOLabel, type, color))
693 return Standard_True;
695 // try to find other shuo
696 aLabels.Remove(aLabels.Length());
699 // attempt to get color exactly of component
700 if (GetColor(aCompLab, type, color))
701 return Standard_True;
703 // attempt to get color of solid
704 TopLoc_Location aLoc;
705 TopoDS_Shape S0 = theShape;
707 TDF_Label aRefLab = ShapeTool()->FindShape(S0);
708 if (!aRefLab.IsNull())
709 return GetColor(aRefLab, type, color);
711 return Standard_False;
714 //=======================================================================
715 //function : IsInstanceVisible
717 //=======================================================================
719 Standard_Boolean XCAFDoc_ColorTool::IsInstanceVisible (const TopoDS_Shape& theShape)
721 // check visibility status of top-level solid, cause it is have highest priority
722 TopLoc_Location NullLoc;
723 TopoDS_Shape S0 = theShape;
724 S0.Location( NullLoc );
725 TDF_Label aRefL = ShapeTool()->FindShape( S0 );
726 if (!aRefL.IsNull() && !IsVisible(aRefL))
727 return Standard_False;
728 // find shuo label structure
729 TDF_LabelSequence aLabels;
730 if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
731 return Standard_True;
732 TDF_Label aCompLab = aLabels.Value(aLabels.Length());
733 // visibility status of component withouts SHUO.
734 if (!IsVisible( aCompLab ))
735 return Standard_False;
736 // check by SHUO structure
737 TDF_LabelSequence aCurLabels;
738 aCurLabels.Append(aCompLab);
739 Standard_Integer i = aLabels.Length() - 1;
740 // while (aCurLabels.Length() < aLabels.Length()) {
742 aCurLabels.Prepend( aLabels.Value(i--) );
743 // get shuo from document by label structure
744 Handle(XCAFDoc_GraphNode) aSHUO;
745 if ( !ShapeTool()->FindSHUO( aCurLabels, aSHUO ) )
747 if ( !IsVisible(aSHUO->Label()) )
748 return Standard_False;
750 return Standard_True; //visible, cause cannot find invisibility status
754 //=======================================================================
755 //function : ReverseTreeNodes
757 //=======================================================================
758 static void ReverseTreeNodes(Handle(TDataStd_TreeNode)& mainNode)
760 if(mainNode->HasFirst()) {
761 Handle(TDataStd_TreeNode) tmpNode;
762 Handle(TDataStd_TreeNode) pNode = mainNode->First();
763 Handle(TDataStd_TreeNode) nNode = pNode->Next();
764 while(!nNode.IsNull()) {
765 tmpNode = pNode->Previous();
766 pNode->SetPrevious(nNode);
767 pNode->SetNext(tmpNode);
769 nNode = pNode->Next();
771 tmpNode = pNode->Previous();
772 pNode->SetPrevious(nNode);
773 pNode->SetNext(tmpNode);
774 mainNode->SetFirst(pNode);
779 //=======================================================================
780 //function : ReverseChainsOfTreeNodes
782 //=======================================================================
784 Standard_Boolean XCAFDoc_ColorTool::ReverseChainsOfTreeNodes()
786 TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
787 for (; it.More(); it.Next()) {
788 TDF_Label aLabel = it.Value()->Label();
789 Handle(TDataStd_TreeNode) mainNode;
790 if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorSurf),mainNode)) {
791 ReverseTreeNodes(mainNode);
793 if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorCurv),mainNode)) {
794 ReverseTreeNodes(mainNode);
796 if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorGen),mainNode)) {
797 ReverseTreeNodes(mainNode);
800 return Standard_True;
803 //=======================================================================
804 //function : DumpJson
806 //=======================================================================
807 void XCAFDoc_ColorTool::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
809 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
811 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
813 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myShapeTool.get())