Integration of OCCT 6.5.0 from SVN
[occt.git] / src / XCAFDoc / XCAFDoc_ColorTool.cxx
1 #include <XCAFDoc_ColorTool.ixx>
2 #include <XCAFDoc.hxx>
3 #include <XCAFDoc_Color.hxx>
4
5 #include <TDF_ChildIDIterator.hxx>
6 #include <TDataStd_TreeNode.hxx>
7 #include <TDataStd_Name.hxx>
8 #include <TNaming_NamedShape.hxx>
9 #include <XCAFDoc_DocumentTool.hxx>
10 #include <XCAFDoc_Color.hxx>
11 #include <TDataStd_UAttribute.hxx>
12 #include <XCAFDoc_GraphNode.hxx>
13
14 #define AUTONAMING // automatically set names for labels
15
16 //=======================================================================
17 //function : BaseLabel
18 //purpose  : 
19 //=======================================================================
20
21 TDF_Label XCAFDoc_ColorTool::BaseLabel() const
22 {
23   return Label();
24 }
25 //=======================================================================
26 //function : ShapeTool
27 //purpose  : 
28 //=======================================================================
29
30 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_ColorTool::ShapeTool() 
31 {
32   if (myShapeTool.IsNull())
33     myShapeTool = XCAFDoc_DocumentTool::ShapeTool(Label());
34   return myShapeTool;
35 }
36
37
38 //=======================================================================
39 //function : IsColor
40 //purpose  : 
41 //=======================================================================
42
43 Standard_Boolean XCAFDoc_ColorTool::IsColor (const TDF_Label& lab) const
44 {
45   Quantity_Color C;
46   return GetColor ( lab, C );
47 }
48
49 //=======================================================================
50 //function : GetColor
51 //purpose  : 
52 //=======================================================================
53
54 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& lab,
55                                                Quantity_Color& col) const
56 {
57   if ( lab.Father() != Label() ) return Standard_False;
58   
59   Handle(XCAFDoc_Color) ColorAttribute;
60   if ( ! lab.FindAttribute ( XCAFDoc_Color::GetID(), ColorAttribute ))
61     return Standard_False;
62   
63   col = ColorAttribute->GetColor();
64   
65   return Standard_True;
66 }
67
68 //=======================================================================
69 //function : FindColor
70 //purpose  : 
71 //=======================================================================
72
73 Standard_Boolean XCAFDoc_ColorTool::FindColor (const Quantity_Color& col, TDF_Label& lab) const
74 {
75   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
76   for (; it.More(); it.Next()) {
77     TDF_Label aLabel = it.Value()->Label();
78     Quantity_Color C;
79     if ( ! GetColor ( aLabel, C ) ) continue;
80     if ( C.IsEqual ( col ) ) {
81       lab = aLabel;
82       return Standard_True;
83     }
84   }
85   return Standard_False;
86 }
87
88 //=======================================================================
89 //function : FindColor
90 //purpose  : 
91 //=======================================================================
92
93 TDF_Label XCAFDoc_ColorTool::FindColor (const Quantity_Color& col) const
94 {
95   TDF_Label L;
96   FindColor ( col, L );
97   return L;
98 }
99
100 //=======================================================================
101 //function : AddColor
102 //purpose  : 
103 //=======================================================================
104
105 TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_Color& col) const
106 {
107   TDF_Label L;
108   if ( FindColor ( col, L ) ) return L;
109
110   // create a new color entry
111   
112   TDF_TagSource aTag;
113   L = aTag.NewChild ( Label() );
114
115   XCAFDoc_Color::Set(L, col);
116   
117 #ifdef AUTONAMING
118   // set name according to color value
119   TCollection_AsciiString str;
120   str += col.StringName ( col.Name() );
121   str += " (";
122   str += TCollection_AsciiString ( col.Red() );
123   str += ",";
124   str += TCollection_AsciiString ( col.Green() );
125   str += ",";
126   str += TCollection_AsciiString ( col.Blue() );
127   str += ")";
128   TDataStd_Name::Set ( L, str );
129 #endif
130   
131   return L;
132 }
133
134 //=======================================================================
135 //function : RemoveColor
136 //purpose  : 
137 //=======================================================================
138
139 void XCAFDoc_ColorTool::RemoveColor (const TDF_Label& lab) const
140 {
141   lab.ForgetAllAttributes (Standard_True);
142 }
143
144 //=======================================================================
145 //function : GetColors
146 //purpose  : 
147 //=======================================================================
148
149 void XCAFDoc_ColorTool::GetColors (TDF_LabelSequence& Labels) const
150 {
151   Labels.Clear();
152
153   TDF_ChildIDIterator ChildIDIterator(Label(),XCAFDoc_Color::GetID()); 
154   for (; ChildIDIterator.More(); ChildIDIterator.Next()) {
155     TDF_Label L = ChildIDIterator.Value()->Label();
156     if ( IsColor ( L ) ) Labels.Append ( L );
157   }
158 }
159
160 //=======================================================================
161 //function : SetColor
162 //purpose  : 
163 //=======================================================================
164
165 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
166                                const TDF_Label& colorL,
167                                const XCAFDoc_ColorType type) const
168 {
169   // set reference
170   Handle(TDataStd_TreeNode) refNode, mainNode;
171   mainNode = TDataStd_TreeNode::Set ( colorL, XCAFDoc::ColorRefGUID(type) );
172   refNode  = TDataStd_TreeNode::Set ( L,      XCAFDoc::ColorRefGUID(type) );
173   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
174   mainNode->Prepend(refNode);
175 }
176
177 //=======================================================================
178 //function : SetColor
179 //purpose  : 
180 //=======================================================================
181
182 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
183                                const Quantity_Color& Color,
184                                const XCAFDoc_ColorType type) const
185 {
186   TDF_Label colorL = AddColor ( Color );
187   SetColor ( L, colorL, type );
188 }
189
190 //=======================================================================
191 //function : UnSetColor
192 //purpose  : 
193 //=======================================================================
194
195 void XCAFDoc_ColorTool::UnSetColor (const TDF_Label& L, const XCAFDoc_ColorType type) const
196 {
197   L.ForgetAttribute ( XCAFDoc::ColorRefGUID(type) );
198 }
199
200 //=======================================================================
201 //function : IsSet
202 //purpose  : 
203 //=======================================================================
204
205 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TDF_Label& L, const XCAFDoc_ColorType type) const
206 {
207   Handle(TDataStd_TreeNode) Node;
208   return L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) && Node->HasFather();
209 }
210
211 //=======================================================================
212 //function : GetColor
213 //purpose  : 
214 //=======================================================================
215
216 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
217                                            const XCAFDoc_ColorType type,
218                                            TDF_Label& colorL) 
219 {
220   Handle(TDataStd_TreeNode) Node;
221   if ( ! L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) ||
222        ! Node->HasFather() ) return Standard_False;
223   colorL = Node->Father()->Label();
224   return Standard_True;
225 }
226
227 //=======================================================================
228 //function : GetColor
229 //purpose  : 
230 //=======================================================================
231
232 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
233                                            const XCAFDoc_ColorType type,
234                                            Quantity_Color& color) 
235 {
236   TDF_Label colorL;
237   if ( ! GetColor ( L, type, colorL ) ) return Standard_False;
238   return GetColor ( colorL, color );
239 }
240
241 //=======================================================================
242 //function : SetColor
243 //purpose  : 
244 //=======================================================================
245
246 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
247                                            const TDF_Label& colorL,
248                                            const XCAFDoc_ColorType type) 
249 {
250   TDF_Label L;
251   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
252   SetColor ( L, colorL, type );
253   return Standard_True;
254 }
255
256 //=======================================================================
257 //function : SetColor
258 //purpose  : 
259 //=======================================================================
260
261 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
262                                            const Quantity_Color& Color,
263                                            const XCAFDoc_ColorType type) 
264 {
265   TDF_Label colorL = AddColor ( Color );
266   return SetColor ( S, colorL, type );
267 }
268
269 //=======================================================================
270 //function : UnSetColor
271 //purpose  : 
272 //=======================================================================
273
274 Standard_Boolean XCAFDoc_ColorTool::UnSetColor (const TopoDS_Shape& S,
275                                              const XCAFDoc_ColorType type) 
276 {
277   TDF_Label L;
278   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
279   UnSetColor ( L, type );
280   return Standard_True;
281 }
282
283 //=======================================================================
284 //function : IsSet
285 //purpose  : 
286 //=======================================================================
287
288 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TopoDS_Shape& S,
289                                         const XCAFDoc_ColorType type) 
290 {
291   TDF_Label L;
292   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
293   return IsSet ( L, type );
294 }
295
296 //=======================================================================
297 //function : GetColor
298 //purpose  : 
299 //=======================================================================
300
301 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S, 
302                                            const XCAFDoc_ColorType type,
303                                            TDF_Label& colorL) 
304 {
305   TDF_Label L;
306   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
307   return GetColor ( L, type, colorL );
308 }
309
310 //=======================================================================
311 //function : GetColor
312 //purpose  : 
313 //=======================================================================
314
315 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S,
316                                            const XCAFDoc_ColorType type,
317                                            Quantity_Color& color) 
318 {
319   TDF_Label colorL;
320   if ( ! GetColor ( S, type, colorL ) ) return Standard_False;
321   return GetColor ( colorL, color );
322 }
323
324 //=======================================================================
325 //function : GetID
326 //purpose  : 
327 //=======================================================================
328
329 const Standard_GUID& XCAFDoc_ColorTool::GetID() 
330 {
331   static Standard_GUID ColorTblID ("efd212ed-6dfd-11d4-b9c8-0060b0ee281b");
332   return ColorTblID; 
333 }
334
335 //=======================================================================
336 //function : Set
337 //purpose  : 
338 //=======================================================================
339
340 Handle(XCAFDoc_ColorTool) XCAFDoc_ColorTool::Set(const TDF_Label& L) 
341 {
342   Handle(XCAFDoc_ColorTool) A;
343   if (!L.FindAttribute (XCAFDoc_ColorTool::GetID(), A)) {
344     A = new XCAFDoc_ColorTool ();
345     L.AddAttribute(A);
346     A->myShapeTool = XCAFDoc_DocumentTool::ShapeTool(L);
347   }
348   return A;
349 }
350
351 //=======================================================================
352 //function : ID
353 //purpose  : 
354 //=======================================================================
355
356 const Standard_GUID& XCAFDoc_ColorTool::ID() const
357 {
358   return GetID();
359 }
360
361 //=======================================================================
362 //function : Restore
363 //purpose  : 
364 //=======================================================================
365
366 void XCAFDoc_ColorTool::Restore(const Handle(TDF_Attribute)& /*with*/) 
367 {
368 }
369
370 //=======================================================================
371 //function : NewEmpty
372 //purpose  : 
373 //=======================================================================
374
375 Handle(TDF_Attribute) XCAFDoc_ColorTool::NewEmpty() const
376 {
377   return new XCAFDoc_ColorTool;
378 }
379
380 //=======================================================================
381 //function : Paste
382 //purpose  : 
383 //=======================================================================
384
385 void XCAFDoc_ColorTool::Paste (const Handle(TDF_Attribute)& /*into*/,
386                                const Handle(TDF_RelocationTable)& /*RT*/) const
387 {
388 }
389
390 /**/
391
392 //=======================================================================
393 //function : XCAFDoc_ColorTool
394 //purpose  : 
395 //=======================================================================
396
397 XCAFDoc_ColorTool::XCAFDoc_ColorTool()
398 {
399 }
400
401 // PTV 23.01.2003 add visibility flag for objects (CAX-IF TRJ11)
402 //=======================================================================
403 //function : IsVisible
404 //purpose  : 
405 //=======================================================================
406
407 Standard_Boolean XCAFDoc_ColorTool::IsVisible (const TDF_Label& L) const
408 {
409   Handle(TDataStd_UAttribute) aUAttr;
410   return (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr));
411 }
412
413 //=======================================================================
414 //function : SetVisibility
415 //purpose  : 
416 //=======================================================================
417
418 void XCAFDoc_ColorTool::SetVisibility (const TDF_Label& L,
419                                        const Standard_Boolean isvisible)
420 {
421   Handle(TDataStd_UAttribute) aUAttr;
422   if (! isvisible ) {
423     Handle(XCAFDoc_GraphNode) aSHUO;
424     if (ShapeTool()->IsShape(L) || ShapeTool()->GetSHUO( L, aSHUO ) )
425       if (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr))
426         aUAttr->Set( L, XCAFDoc::InvisibleGUID() );
427   }
428   else L.ForgetAttribute( XCAFDoc::InvisibleGUID() );
429 }
430
431 //=======================================================================
432 //function : SetInstanceColor
433 //purpose  : 
434 //=======================================================================
435
436 Standard_Boolean XCAFDoc_ColorTool::SetInstanceColor (const TopoDS_Shape& theShape,
437                                                       const XCAFDoc_ColorType type,
438                                                       const Quantity_Color& color,
439                                                       const Standard_Boolean IsCreateSHUO)
440 {
441   // find shuo label structure 
442   TDF_LabelSequence aLabels;
443   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
444     return Standard_False;
445   Handle(XCAFDoc_GraphNode) aSHUO;
446   // set the SHUO structure for this component if it is not exist
447   if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) )
448     if (aLabels.Length() == 1) {
449       // set color directly for component as NAUO
450       SetColor(aLabels.Value(1), color, type);
451       return Standard_True;
452     }
453     else if ( !IsCreateSHUO ||  !ShapeTool()->SetSHUO( aLabels, aSHUO ) )
454       return Standard_False;
455   TDF_Label aSHUOLabel = aSHUO->Label();
456   SetColor( aSHUOLabel, color, type );
457   return Standard_True;
458 }
459
460 //=======================================================================
461 //function : GetInstanceColor
462 //purpose  : 
463 //=======================================================================
464
465 Standard_Boolean XCAFDoc_ColorTool::GetInstanceColor (const TopoDS_Shape& theShape,
466                                                       const XCAFDoc_ColorType type,
467                                                       Quantity_Color& color)
468 {
469   // find shuo label structure 
470   TDF_LabelSequence aLabels;
471   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
472     return Standard_False;
473   Handle(XCAFDoc_GraphNode) aSHUO;
474   // get shuo from document by label structure
475   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
476   while (aLabels.Length() > 1) {
477     if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) ) {
478       // try to find other shuo 
479       aLabels.Remove(aLabels.Length());
480       continue;
481     } else {
482       TDF_Label aSHUOLabel = aSHUO->Label();
483       if (GetColor ( aSHUOLabel, type, color ) )
484         return Standard_True;
485       else 
486         // try to find other shuo 
487         aLabels.Remove(aLabels.Length());
488     }
489   }
490   // attempt to get color exactly of component
491   if (GetColor( aCompLab, type, color ))
492     return Standard_True;
493   
494   // attempt to get color of solid
495   TopLoc_Location aLoc;
496   TopoDS_Shape S0 = theShape;
497   S0.Location( aLoc );
498   TDF_Label aRefLab = ShapeTool()->FindShape( S0 );
499   if (!aRefLab.IsNull())
500     return GetColor( aRefLab, type, color );
501   // no color assigned
502   return Standard_False;
503 }
504
505 //=======================================================================
506 //function : IsInstanceVisible
507 //purpose  : 
508 //=======================================================================
509
510 Standard_Boolean XCAFDoc_ColorTool::IsInstanceVisible (const TopoDS_Shape& theShape)
511 {
512   // check visibility status of top-level solid, cause it is have highest priority
513   TopLoc_Location NullLoc;
514   TopoDS_Shape S0 = theShape;
515   S0.Location( NullLoc );
516   TDF_Label aRefL = ShapeTool()->FindShape( S0 );
517   if (!aRefL.IsNull() && !IsVisible(aRefL))
518     return Standard_False;
519   // find shuo label structure 
520   TDF_LabelSequence aLabels;
521   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
522     return Standard_True;
523   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
524   // visibility status of component withouts SHUO.
525   if (!IsVisible( aCompLab ))
526     return Standard_False;
527   // check by SHUO structure
528   TDF_LabelSequence aCurLabels;
529   aCurLabels.Append(aCompLab);
530   Standard_Integer i = aLabels.Length() - 1;
531   //   while (aCurLabels.Length() < aLabels.Length()) {
532   while (i >= 1) {
533     aCurLabels.Prepend( aLabels.Value(i--) );
534     // get shuo from document by label structure
535     Handle(XCAFDoc_GraphNode) aSHUO;
536     if ( !ShapeTool()->FindSHUO( aCurLabels, aSHUO ) )
537       continue;
538     if ( !IsVisible(aSHUO->Label()) )
539       return Standard_False;
540   }
541   return Standard_True; //visible, cause cannot find invisibility status
542 }
543
544
545 //=======================================================================
546 //function : ReverseTreeNodes
547 //purpose  : auxilary
548 //=======================================================================
549 static void ReverseTreeNodes(Handle(TDataStd_TreeNode)& mainNode)
550 {
551   if(mainNode->HasFirst()) {
552     Handle(TDataStd_TreeNode) tmpNode;
553     Handle(TDataStd_TreeNode) pNode = mainNode->First();
554     Handle(TDataStd_TreeNode) nNode = pNode->Next();
555     while(!nNode.IsNull()) {
556       tmpNode = pNode->Previous();
557       pNode->SetPrevious(nNode);
558       pNode->SetNext(tmpNode);
559       pNode = nNode;
560       nNode = pNode->Next();
561     }
562     tmpNode = pNode->Previous();
563     pNode->SetPrevious(nNode);
564     pNode->SetNext(tmpNode);
565     mainNode->SetFirst(pNode);
566   }
567 }
568
569
570 //=======================================================================
571 //function : ReverseChainsOfTreeNodes
572 //purpose  : 
573 //=======================================================================
574
575 Standard_Boolean XCAFDoc_ColorTool::ReverseChainsOfTreeNodes()
576 {
577   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
578   for (; it.More(); it.Next()) {
579     TDF_Label aLabel = it.Value()->Label();
580     Handle(TDataStd_TreeNode) mainNode;
581     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorSurf),mainNode)) {
582       ReverseTreeNodes(mainNode);
583     }
584     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorCurv),mainNode)) {
585       ReverseTreeNodes(mainNode);
586     }
587     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorGen),mainNode)) {
588       ReverseTreeNodes(mainNode);
589     }
590   }
591   return Standard_True;
592 }