Fix T48366: Freestyle will unnecessary exclude some linked objects.

Group membership testing for including/excluding feature lines was not
accounting for object names possibly further qualified by library file
paths.

Also fixed a few potential (but unlikely) references of uninitialized
variables.

A big thank to Bastien Montagne for the insight on the cause of the
problem and how to fix it.
This commit is contained in:
Tamito Kajiyama 2016-08-05 22:21:43 +09:00
parent bed32bf004
commit a2a7316d92
10 changed files with 82 additions and 3 deletions

@ -914,14 +914,25 @@ class QuantitativeInvisibilityRangeUP1D(UnaryPredicate1D):
return self.qi_start <= qi <= self.qi_end return self.qi_start <= qi <= self.qi_end
def getQualifiedObjectName(ob):
if ob.library is not None:
return ob.library.filepath + '/' + ob.name
return ob.name
class ObjectNamesUP1D(UnaryPredicate1D): class ObjectNamesUP1D(UnaryPredicate1D):
def __init__(self, names, negative): def __init__(self, names, negative):
UnaryPredicate1D.__init__(self) UnaryPredicate1D.__init__(self)
self.names = names self.names = names
self.negative = negative self.negative = negative
def getViewShapeName(self, vs):
if vs.library_path is not None:
return vs.library_path + '/' + vs.name
return vs.name
def __call__(self, viewEdge): def __call__(self, viewEdge):
found = viewEdge.viewshape.name in self.names found = self.getViewShapeName(viewEdge.viewshape) in self.names
if self.negative: if self.negative:
return not found return not found
return found return found
@ -1256,7 +1267,7 @@ def process(layer_name, lineset_name):
# prepare selection criteria by group of objects # prepare selection criteria by group of objects
if lineset.select_by_group: if lineset.select_by_group:
if lineset.group is not None: if lineset.group is not None:
names = {ob.name: True for ob in lineset.group.objects} names = {getQualifiedObjectName(ob): True for ob in lineset.group.objects}
upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE') upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE')
selection_criteria.append(upred) selection_criteria.append(upred)
# prepare selection criteria by image border # prepare selection criteria by image border

@ -807,6 +807,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
// sets the id of the rep // sets the id of the rep
rep->setId(Id(id, 0)); rep->setId(Id(id, 0));
rep->setName(obi->ob->id.name + 2); rep->setName(obi->ob->id.name + 2);
rep->setLibraryPath(obi->ob->id.lib ? obi->ob->id.lib->name : NULL);
const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]), const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]),
Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2])); Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2]));

@ -296,6 +296,19 @@ static PyObject *ViewShape_name_get(BPy_ViewShape *self, void *UNUSED(closure))
return PyUnicode_FromString(self->vs->getName()); return PyUnicode_FromString(self->vs->getName());
} }
PyDoc_STRVAR(ViewShape_library_path_doc,
"The library path of the ViewShape.\n"
"\n"
":type: str, or None if the ViewShape is not part of a library");
static PyObject *ViewShape_library_path_get(BPy_ViewShape *self, void *UNUSED(closure))
{
const char *name = self->vs->getLibraryPath();
if (!name)
Py_RETURN_NONE;
return PyUnicode_FromString(name);
}
PyDoc_STRVAR(ViewShape_id_doc, PyDoc_STRVAR(ViewShape_id_doc,
"The Id of this ViewShape.\n" "The Id of this ViewShape.\n"
"\n" "\n"
@ -313,6 +326,7 @@ static PyGetSetDef BPy_ViewShape_getseters[] = {
(char *)ViewShape_vertices_doc, NULL}, (char *)ViewShape_vertices_doc, NULL},
{(char *)"edges", (getter)ViewShape_edges_get, (setter)ViewShape_edges_set, (char *)ViewShape_edges_doc, NULL}, {(char *)"edges", (getter)ViewShape_edges_get, (setter)ViewShape_edges_set, (char *)ViewShape_edges_doc, NULL},
{(char *)"name", (getter)ViewShape_name_get, (setter)NULL, (char *)ViewShape_name_doc, NULL}, {(char *)"name", (getter)ViewShape_name_get, (setter)NULL, (char *)ViewShape_name_doc, NULL},
{(char *)"library_path", (getter)ViewShape_library_path_get, (setter)NULL, (char *)ViewShape_library_path_doc, NULL},
{(char *)"id", (getter)ViewShape_id_get, (setter)NULL, (char *)ViewShape_id_doc, NULL}, {(char *)"id", (getter)ViewShape_id_get, (setter)NULL, (char *)ViewShape_id_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
}; };

@ -48,6 +48,8 @@ public:
inline Rep() : BaseObject() inline Rep() : BaseObject()
{ {
_Id = 0; _Id = 0;
_Name = 0;
_LibraryPath = 0;
_FrsMaterial = 0; _FrsMaterial = 0;
} }
@ -55,6 +57,7 @@ public:
{ {
_Id = iBrother._Id; _Id = iBrother._Id;
_Name = iBrother._Name; _Name = iBrother._Name;
_LibraryPath = iBrother._LibraryPath;
if (0 == iBrother._FrsMaterial) if (0 == iBrother._FrsMaterial)
_FrsMaterial = 0; _FrsMaterial = 0;
else else
@ -68,6 +71,7 @@ public:
std::swap(_BBox, ioOther._BBox); std::swap(_BBox, ioOther._BBox);
std::swap(_Id, ioOther._Id); std::swap(_Id, ioOther._Id);
std::swap(_Name, ioOther._Name); std::swap(_Name, ioOther._Name);
std::swap(_LibraryPath, ioOther._LibraryPath);
std::swap(_FrsMaterial, ioOther._FrsMaterial); std::swap(_FrsMaterial, ioOther._FrsMaterial);
} }
@ -76,6 +80,7 @@ public:
if (&iBrother != this) { if (&iBrother != this) {
_Id = iBrother._Id; _Id = iBrother._Id;
_Name = iBrother._Name; _Name = iBrother._Name;
_LibraryPath = iBrother._LibraryPath;
if (0 == iBrother._FrsMaterial) { if (0 == iBrother._FrsMaterial) {
_FrsMaterial = 0; _FrsMaterial = 0;
} }
@ -132,6 +137,11 @@ public:
return _Name; return _Name;
} }
inline const char *getLibraryPath() const
{
return _LibraryPath;
}
inline const FrsMaterial *frs_material() const inline const FrsMaterial *frs_material() const
{ {
return _FrsMaterial; return _FrsMaterial;
@ -153,6 +163,11 @@ public:
_Name = name; _Name = name;
} }
inline void setLibraryPath(const char *path)
{
_LibraryPath = path;
}
inline void setFrsMaterial(const FrsMaterial& iMaterial) inline void setFrsMaterial(const FrsMaterial& iMaterial)
{ {
_FrsMaterial = new FrsMaterial(iMaterial); _FrsMaterial = new FrsMaterial(iMaterial);
@ -162,6 +177,7 @@ private:
BBox<Vec3f> _BBox; BBox<Vec3f> _BBox;
Id _Id; Id _Id;
const char *_Name; const char *_Name;
const char *_LibraryPath;
FrsMaterial *_FrsMaterial; FrsMaterial *_FrsMaterial;
}; };

@ -1416,6 +1416,7 @@ private:
vector<FEdge*> _edgesList; // list of all edges vector<FEdge*> _edgesList; // list of all edges
Id _Id; Id _Id;
const char *_Name; const char *_Name;
const char *_LibraryPath;
BBox<Vec3r> _BBox; BBox<Vec3r> _BBox;
vector<FrsMaterial> _FrsMaterials; vector<FrsMaterial> _FrsMaterials;
@ -1436,6 +1437,7 @@ public:
_importance = 0.0f; _importance = 0.0f;
_ViewShape = NULL; _ViewShape = NULL;
_Name = NULL; _Name = NULL;
_LibraryPath = NULL;
} }
/*! Copy constructor */ /*! Copy constructor */
@ -1444,6 +1446,7 @@ public:
userdata = NULL; userdata = NULL;
_Id = iBrother._Id; _Id = iBrother._Id;
_Name = iBrother._Name; _Name = iBrother._Name;
_LibraryPath = iBrother._LibraryPath;
_BBox = iBrother.bbox(); _BBox = iBrother.bbox();
_FrsMaterials = iBrother._FrsMaterials; _FrsMaterials = iBrother._FrsMaterials;
_importance = iBrother._importance; _importance = iBrother._importance;
@ -1893,6 +1896,12 @@ public:
return _Name; return _Name;
} }
/*! Returns the library path of the Shape. */
inline const char *getLibraryPath() const
{
return _LibraryPath;
}
/* Modififers */ /* Modififers */
/*! Sets the Id of the shape.*/ /*! Sets the Id of the shape.*/
inline void setId(Id id) inline void setId(Id id)
@ -1906,6 +1915,12 @@ public:
_Name = name; _Name = name;
} }
/*! Sets the library path of the shape.*/
inline void setLibraryPath(const char *path)
{
_LibraryPath = path;
}
/*! Sets the list of materials for the shape */ /*! Sets the list of materials for the shape */
inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials)
{ {

@ -1565,12 +1565,18 @@ public:
return _SShape->getId(); return _SShape->getId();
} }
/*! Returns the ViewShape id. */ /*! Returns the ViewShape name. */
inline const char *getName() const inline const char *getName() const
{ {
return _SShape->getName(); return _SShape->getName();
} }
/*! Returns the ViewShape library path. */
inline const char *getLibraryPath() const
{
return _SShape->getLibraryPath();
}
/* modifiers */ /* modifiers */
/*! Sets the SShape on top of which the ViewShape is built. */ /*! Sets the SShape on top of which the ViewShape is built. */
inline void setSShape(SShape *iSShape) inline void setSShape(SShape *iSShape)

@ -1204,6 +1204,7 @@ void ViewMapBuilder::computeInitialViewEdges(WingedEdge& we)
psShape = new SShape; psShape = new SShape;
psShape->setId((*it)->GetId()); psShape->setId((*it)->GetId());
psShape->setName((*it)->getName()); psShape->setName((*it)->getName());
psShape->setLibraryPath((*it)->getLibraryPath());
psShape->setFrsMaterials((*it)->frs_materials()); // FIXME psShape->setFrsMaterials((*it)->frs_materials()); // FIXME
// create the view shape // create the view shape

@ -471,6 +471,7 @@ WShape::WShape(WShape& iBrother)
{ {
_Id = iBrother.GetId(); _Id = iBrother.GetId();
_Name = iBrother._Name; _Name = iBrother._Name;
_LibraryPath = iBrother._LibraryPath;
_FrsMaterials = iBrother._FrsMaterials; _FrsMaterials = iBrother._FrsMaterials;
#if 0 #if 0
_meanEdgeSize = iBrother._meanEdgeSize; _meanEdgeSize = iBrother._meanEdgeSize;

@ -1025,6 +1025,7 @@ protected:
vector<WFace *> _FaceList; vector<WFace *> _FaceList;
int _Id; int _Id;
const char *_Name; const char *_Name;
const char *_LibraryPath;
static unsigned _SceneCurrentId; static unsigned _SceneCurrentId;
#if 0 #if 0
Vec3f _min; Vec3f _min;
@ -1043,6 +1044,8 @@ public:
#endif #endif
_Id = _SceneCurrentId; _Id = _SceneCurrentId;
_SceneCurrentId++; _SceneCurrentId++;
_Name = 0;
_LibraryPath = 0;
} }
/*! copy constructor */ /*! copy constructor */
@ -1127,6 +1130,11 @@ public:
return _Name; return _Name;
} }
inline const char *getLibraryPath() const
{
return _LibraryPath;
}
/*! modifiers */ /*! modifiers */
static inline void setCurrentId(const unsigned id) static inline void setCurrentId(const unsigned id)
{ {
@ -1176,6 +1184,11 @@ public:
_Name = name; _Name = name;
} }
inline void setLibraryPath(const char *path)
{
_LibraryPath = path;
}
/*! designed to build a specialized WFace for use in MakeFace */ /*! designed to build a specialized WFace for use in MakeFace */
virtual WFace *instanciateFace() const virtual WFace *instanciateFace() const
{ {

@ -42,6 +42,7 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
} }
shape->setId(ifs.getId().getFirst()); shape->setId(ifs.getId().getFirst());
shape->setName(ifs.getName()); shape->setName(ifs.getName());
shape->setLibraryPath(ifs.getLibraryPath());
//ifs.setId(shape->GetId()); //ifs.setId(shape->GetId());
} }