How set different colors of shapes inside TopoDS_Compound?

Hello!
I need to display about 1500 spheres with different sizes and colors. I use TopoDS_Compound to increase speed. Say me, how to set differrent colors of the spheres inside compound? Thanks. My code:

myContext = getContext();

TopoDS_Compound compoundShape;
BRep_Builder compoundBuilder;
compoundBuilder.MakeCompound( compoundShape );

// pnts_count - number of spheres
for(int i=0;i
{
// color and scale factor of current sphere
float R = my_color_red;
float G = my_color_green;
float B = my_color_blue;
int scf = my_scale_factor;

// coordinates of current sphere
float X = my_X;
float Y = my_Y;
float Z = my_Z;

compoundBuilder.Add(compoundShape, BRepPrimAPI_MakeSphere(gp_Pnt(X,Y, Z), 3+scf));
}

Handle(AIS_Shape) HNDL_spheres = new AIS_Shape(compoundShape);
myContext->Display(HNDL_spheres,1,-1,false,false);

Pawel's picture

Hello Oleg,

I'm afraid you would have to derive from AIS_IteractiveObject in order to implement your own (colorizing) visualization routine.

Pawel

JuryS's picture

Hello, Oleg !
I think that you need create group with TDF_Label and than you can insert objects in this group with different materials/colors/textures.

Create your ouwn classes of group object and define there highlight/select methods, insert/extract methods, compute of compound of group and all that you need by using OCC Application framwork toolkits.

Oleg Kulikov's picture

Thank you! But can you give me code example?

JuryS's picture

In my case Group is a label that contains all tags off objects that included in this Group. You may use QSet or QVector to collect their tags.

And than create your group like this:

void creategroup::GroupByVect(uint &aTag,const TDF_Label &MainLab,
const QVector &aObjVectors,const QString &Name)
{
// Group Label
// 0 -- your object type
// 0:0 -- name
// 1 -- dummy
// 2 -- all included labels tags (2:0,2:1,2:2 ... 2:n)
// 3 --
// 3:0 -- dummy
// 3:1 -- bounding box of all objects of group (may be used for move, preview of group of objects...)

//New Label
TDF_Label L = TDF_TagSource::NewChild(MainLab);

//Driver name
TDataStd_AsciiString::Set(L, "Group");

//Name of object
TDF_Label level0 = L.FindChild(0,true);
TDataStd_AsciiString::Set(level0.FindChild(0), Name.toAscii().data());

//TAGS of objects
TDF_Label level2 = L.FindChild(2,true);

for (int i = 0; i < aObjVectors.size(); ++i)
{
TDataStd_Integer::Set(level2.FindChild(i), aObjVectors.at(i));

TDF_Label ObjLabel = MainLab.FindChild(aObjVectors.at(i)).FindChild(3,true);
TDataStd_Integer::Set(ObjLabel.FindChild(0),L.Tag());
}

//Adding the boundBox
GroupTools::RecalcGroup(L,aObjVectors);

//result label
aTag = L.Tag();
}

Oleg Kulikov's picture

Thank you very much. But linker return error
creategroup.obj : error LNK2019: unresolved external symbol "public: static class TDF_Label __cdecl TDF_TagSource::NewChild(class TDF_Label const &)" (?NewChild@TDF_TagSource@@SA?AVTDF_Label@@ABV2@@Z) referenced in function "public: void __thiscall creategroup::GroupByVect(unsigned int &,class TDF_Label const &,class QVector const &,class QString const &)" (?GroupByVect@creategroup@@QAEXAAIABVTDF_Label@@ABV?$QVector@I@@ABVQString@@@Z)

my code:
creategroup.cpp:

#include "creategroup.h"

creategroup::creategroup(void)
{
}

creategroup::~creategroup(void)
{
}

void creategroup::GroupByVect(uint &aTag,const TDF_Label &MainLab,
const QVector &aObjVectors,const QString &Name)
{
// Group Label
// 0 -- your object type
// 0:0 -- name
// 1 -- dummy
// 2 -- all included labels tags (2:0,2:1,2:2 ... 2:n)
// 3 --
// 3:0 -- dummy
// 3:1 -- bounding box of all objects of group (may be used for move, preview of group of objects...)

//New Label
TDF_Label L = TDF_TagSource::NewChild(MainLab);

//Driver name
TDataStd_AsciiString::Set(L, "Group");

//Name of object
TDF_Label level0 = L.FindChild(0,true);
TDataStd_AsciiString::Set(level0.FindChild(0), Name.toAscii().data());

//TAGS of objects
TDF_Label level2 = L.FindChild(2,true);

for (int i = 0; i < aObjVectors.size(); ++i)
{
TDataStd_Integer::Set(level2.FindChild(i), aObjVectors.at(i));

TDF_Label ObjLabel = MainLab.FindChild(aObjVectors.at(i)).FindChild(3,true);
TDataStd_Integer::Set(ObjLabel.FindChild(0),L.Tag());
}

//Adding the boundBox
GroupTools::RecalcGroup(L,aObjVectors);

//result label
aTag = L.Tag();
}

creategroup.h:

#pragma once

#include
#include
#include
#include

#include

#include
#include

#include
#include
#include
#include "TNaming_Builder.hxx"
#include "BRepBuilderAPI_MakeVertex.hxx"
#include
#include
#include

class creategroup
{
public:

void GroupByVect(uint &aTag,const TDF_Label &MainLab, const QVector &aObjVectors,const QString &Name);

creategroup(void);
~creategroup(void);
};

JuryS's picture

You have this error because in your headers files you have this classes/functions, but you don't complile your application with librarys.

add in your project librarys of OpenCascade, something like
LIBS = ./../Lib660/MINGW32/lib/libTkBrep.a \
./../Lib660/MINGW32/lib/libTkG2d.a \
./../Lib660/MINGW32/lib/libTkG3d.a \

or

./../Lib660/MINGW32/lib/libTkKernel.a \
./../Lib660/MINGW32/lib/libTkMath.a \
if you are using mingw, insert all librarys of OCC

JuryS's picture

Many sorry... librarys under MSVC ends with *.lib extensions..
LIBS = .................
#ApplicationFramework:
./../Librarys/MSVC32/lib/TkDocCDF.lib \
./../Librarys/MSVC32/lib/TkDocCAF.lib \
./../Librarys/MSVC32/lib/TkDocBinL.lib \
./../Librarys/MSVC32/lib/TkDocXmlL.lib \
./../Librarys/MSVC32/lib/TkDocBin.lib \
./../Librarys/MSVC32/lib/TkDocXml.lib

Oleg Kulikov's picture

Thank you. But I don't have this libraries in my OpenCASCADE directory. There are only this libs:
c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\TKCAF.lib
c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\TKBinL.lib
c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\TKXmlL.lib
c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\TKBin.lib
c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\TKXml.lib
adding this to my MSVS project take no effect.

Oleg Kulikov's picture

Yuriy, I add all libraries from dir c:\OpenCASCADE6.5.1\ros\win32\vc8\lib\ to my project, and its successfully run. Thank you!

Oleg Kulikov's picture

Yuriy, once more question. Where I can get OCAF code examples? Application Framework
User’s Guide have no useful examples. Thanks!

JuryS's picture

We have only OCC samples with OCAF code. Ask me what functions you are need to realize?

TDF_Labels like a tree. You have graphical objects and you collect their data in this tree by labels. In your previos question you collect your objects with different colors/materials. What is group? Only 2 things that you are really need: it's a objects Names/Tags that you insert in this tree (for group operations like insert new objects in group or extract object) and highlight all objects in group when you move mouse on the screen (in some actions; also you highlight objects by their tags)

In your case: at this moment you can extract from group label all objects that you insert in your group? If not - I will try to give examples of functions?

Forum supervisor's picture

Dear Oleg,
Also you can find some code examples in "OPEN CASCADE APPLICATION FRAMEWORK FUNCTION MECHANISM USER’S GUIDE" and Draw related packages like: DDF, DDataStd,DDocStd,DNaming...
In addition we can propose you several more advanced OCAF samples on a payed basis.
If you are interested in such examples you may contact us us via the Contact Form http://www.opencascade.org/about/contacts/.
Regards

Mik Wind's picture

This is probably too late for OP, however for those like me that stumbled upon this thread when searching for a solution,

it is possible to use AIS_ColoredShape to solve this.

source: https://www.opencascade.com/doc/occt-7.0.0/overview/html/occt_user_guides__visualization.html#occt_visu_2

The class AIS_ColoredShape allows using custom colors and line widths for TopoDS_Shape objects and their sub-shapes.

AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);

// setup color of entire shape

aColoredShape->SetColor (Quantity_Color (Quantity_NOC_RED));

// setup line width of entire shape

 aColoredShape->SetWidth (1.0);

// set transparency value

aColoredShape->SetTransparency (0.5);

// customize color of specified sub-shape

aColoredShape->SetCustomColor (theSubShape, Quantity_Color (Quantity_NOC_BLUE1));

// customize line width of specified sub-shape

aColoredShape->SetCustomWidth (theSubShape, 0.25);