0000439: Improve STEP import to find colors attached to sub-shapes

git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5396 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
wmayer 2012-01-11 16:10:41 +00:00
parent 2d0ff3b8a7
commit 312f2b686d

View File

@ -37,6 +37,7 @@
# include <XCAFDoc_DocumentTool.hxx>
# include <XCAFDoc_ShapeTool.hxx>
# include <XCAFDoc_ColorTool.hxx>
# include <XCAFDoc_Location.hxx>
# include <TDF_Label.hxx>
# include <TDF_LabelSequence.hxx>
# include <TDF_ChildIterator.hxx>
@ -71,6 +72,191 @@
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/ProgressIndicator.h>
class ImportOCAF
{
public:
ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
: pDoc(h), doc(d), default_name(name)
{
aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main());
aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main());
}
void loadShapes();
private:
void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, bool isRef);
void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&);
void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&);
private:
Handle_TDocStd_Document pDoc;
App::Document* doc;
Handle_XCAFDoc_ShapeTool aShapeTool;
Handle_XCAFDoc_ColorTool aColorTool;
std::string default_name;
std::set<int> myRefShapes;
static const int HashUpper = INT_MAX;
};
void ImportOCAF::loadShapes()
{
myRefShapes.clear();
loadShapes(pDoc->Main(), TopLoc_Location(), default_name, false);
}
void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, bool isRef)
{
int hash = 0;
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
hash = aShape.HashCode(HashUpper);
}
Handle(TDataStd_Name) name;
std::string part_name = defaultname;
if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
TCollection_ExtendedString extstr = name->Get();
char* str = new char[extstr.LengthOfCString()+1];
extstr.ToUTF8CString(str);
part_name = str;
delete [] str;
if (part_name.empty()) {
part_name = defaultname;
}
else {
bool ws=true;
for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) {
if (*it != ' ') {
ws = false;
break;
}
}
if (ws)
part_name = defaultname;
}
}
TopLoc_Location part_loc = loc;
Handle(XCAFDoc_Location) hLoc;
if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) {
part_loc = hLoc->Get();
}
#ifdef FC_DEBUG
Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n",
hash,
part_name.c_str(),
aShapeTool->IsTopLevel(label),
aShapeTool->IsAssembly(label),
aShapeTool->IsShape(label),
aShapeTool->IsCompound(label),
aShapeTool->IsSimpleShape(label),
aShapeTool->IsFree(label),
aShapeTool->IsReference(label),
aShapeTool->IsComponent(label),
aShapeTool->IsSubShape(label)
);
#endif
TDF_Label ref;
if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) {
loadShapes(ref, part_loc, part_name, true);
}
if (isRef || myRefShapes.find(hash) == myRefShapes.end()) {
TopoDS_Shape aShape;
if (isRef && aShapeTool->GetShape(label, aShape))
myRefShapes.insert(aShape.HashCode(HashUpper));
if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) {
if (isRef)
createShape( label, loc, defaultname );
else
createShape( label, part_loc, part_name );
}
else {
for (TDF_ChildIterator it(label); it.More(); it.Next()) {
loadShapes(it.Value(), part_loc, part_name, isRef);
}
}
}
}
void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name)
{
const TopoDS_Shape& aShape = aShapeTool->GetShape(label);
if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) {
TopExp_Explorer xp;
int ctSolids = 0, ctShells = 0;
for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
createShape(xp.Current(), loc, name);
for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
createShape(xp.Current(), loc, name);
if (ctSolids > 0 || ctShells > 0)
return;
}
createShape(aShape, loc, name);
}
void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name)
{
Part::Feature* part = static_cast<Part::Feature*>(doc->addObject("Part::Feature"));
if (!loc.IsIdentity())
part->Shape.setValue(aShape.Located(loc));
else
part->Shape.setValue(aShape);
part->Label.setValue(name);
Quantity_Color aColor;
App::Color color(0.8f,0.8f,0.8f);
if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) {
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
}
}
TopTools_IndexedMapOfShape faces;
TopExp_Explorer xp(aShape,TopAbs_FACE);
while (xp.More()) {
faces.Add(xp.Current());
xp.Next();
}
bool found_face_color = false;
std::vector<App::Color> faceColors;
faceColors.resize(faces.Extent(), color);
xp.Init(aShape,TopAbs_FACE);
while (xp.More()) {
if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) ||
aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) {
int index = faces.FindIndex(xp.Current());
color.r = aColor.Red();
color.g = aColor.Green();
color.b = aColor.Blue();
faceColors[index-1] = color;
found_face_color = true;
}
xp.Next();
}
if (found_face_color) {
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
}
}
}
class ImportXCAF
{
public:
@ -190,6 +376,12 @@ private:
{
TopoDS_Shape aShape;
if (aShapeTool->GetShape(label,aShape)) {
//if (aShapeTool->IsReference(label)) {
// TDF_Label reflabel;
// if (aShapeTool->GetReferredShape(label, reflabel)) {
// loadShapes(reflabel);
// }
//}
if (aShapeTool->IsTopLevel(label)) {
int ctSolids = 0, ctShells = 0, ctComps = 0;
// add the shapes
@ -248,6 +440,18 @@ private:
delete [] str;
}
#if 0
// http://www.opencascade.org/org/forum/thread_15174/
if (aShapeTool->IsAssembly(label)) {
TDF_LabelSequence shapeLabels;
aShapeTool->GetComponents(label, shapeLabels);
Standard_Integer nbShapes = shapeLabels.Length();
for (Standard_Integer i = 1; i <= nbShapes; i++) {
loadShapes(shapeLabels.Value(i));
}
}
#endif
if (label.HasChild()) {
TDF_ChildIterator it;
for (it.Initialize(label); it.More(); it.Next()) {
@ -313,6 +517,9 @@ static PyObject * importer(PyObject *self, PyObject *args)
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
IGESCAFControl_Reader aReader;
aReader.SetColorMode(true);
aReader.SetNameMode(true);
aReader.SetLayerMode(true);
if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) {
PyErr_SetString(PyExc_Exception, "cannot read IGES file");
return 0;
@ -330,8 +537,13 @@ static PyObject * importer(PyObject *self, PyObject *args)
return 0;
}
#if 1
ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure());
ocaf.loadShapes();
#else
ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure());
xcaf.loadShapes();
#endif
pcDoc->recompute();
}