Skip to content

Commit d009246

Browse files
committed
Fem: Fix Mesh coloring
1 parent b509511 commit d009246

4 files changed

+234
-80
lines changed

src/Gui/ViewProviderGeometryObject.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,14 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
179179
long value = toPercent(ShapeAppearance.getTransparency());
180180
if (value != Transparency.getValue()) {
181181
float trans = fromPercent(Transparency.getValue());
182-
pcShapeMaterial->transparency = trans;
182+
183+
float* t = pcShapeMaterial->transparency.startEditing();
184+
int tNum = pcShapeMaterial->transparency.getNum();
185+
for (int i= 0; i < tNum; ++i) {
186+
t[i] = trans;
187+
}
188+
189+
pcShapeMaterial->transparency.finishEditing();
183190
ShapeAppearance.setTransparency(trans);
184191
}
185192
}

src/Mod/Fem/Gui/ViewProviderFemMesh.cpp

+185-68
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject)
186186

187187
App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0, 64.0, 1.0};
188188

189+
const char* ViewProviderFemMesh::colorModeEnum[] = {"Overall", "ByElement", "ByNode", nullptr};
190+
189191
ViewProviderFemMesh::ViewProviderFemMesh()
190192
{
191193
sPixmap = "fem-femmesh-from-shape";
@@ -202,6 +204,23 @@ ViewProviderFemMesh::ViewProviderFemMesh()
202204
ADD_PROPERTY(ShowInner, (false));
203205
ADD_PROPERTY(MaxFacesShowInner, (50000));
204206

207+
ADD_PROPERTY_TYPE(ColorMode,
208+
("Overall"),
209+
"Display Options",
210+
App::Prop_None,
211+
"Set the color mode");
212+
ColorMode.setEnums(colorModeEnum);
213+
ADD_PROPERTY_TYPE(NodeColorArray,
214+
(PointColor.getValue()),
215+
"Object Style",
216+
App::Prop_Hidden,
217+
"Node diffuse color array");
218+
ADD_PROPERTY_TYPE(ElementColorArray,
219+
(ShapeAppearance.getDiffuseColor()),
220+
"Object Style",
221+
App::Prop_Hidden,
222+
"Node diffuse color array");
223+
205224
onlyEdges = false;
206225

207226
pcDrawStyle = new SoDrawStyle();
@@ -413,6 +432,29 @@ void ViewProviderFemMesh::onChanged(const App::Property* prop)
413432
else if (prop == &LineWidth) {
414433
pcDrawStyle->lineWidth = LineWidth.getValue();
415434
}
435+
else if (prop == &ColorMode) {
436+
switch (ColorMode.getValue()) {
437+
case 1: // ByElement
438+
setMaterialByColorArray(&ElementColorArray, vFaceElementIdx);
439+
break;
440+
case 2: // ByNode
441+
setMaterialByColorArray(&NodeColorArray, vNodeElementIdx);
442+
break;
443+
default: // Overall
444+
ShapeAppearance.touch();
445+
}
446+
}
447+
else if (prop == &ShapeAppearance && ColorMode.getValue() != 0) {
448+
// nothing
449+
}
450+
else if ((prop == &ElementColorArray || prop == &Transparency) && ColorMode.getValue() == 1) {
451+
setMaterialByColorArray(&ElementColorArray, vFaceElementIdx);
452+
printf("elem prop\n");
453+
}
454+
else if ((prop == &NodeColorArray || prop == &Transparency) && ColorMode.getValue() == 2) {
455+
setMaterialByColorArray(&NodeColorArray, vNodeElementIdx);
456+
printf("node prop\n");
457+
}
416458
else {
417459
ViewProviderGeometryObject::onChanged(prop);
418460
}
@@ -549,58 +591,6 @@ PyObject* ViewProviderFemMesh::getPyObject()
549591
return Py::new_reference_to(PythonObject);
550592
}
551593

552-
void ViewProviderFemMesh::setColorByNodeId(const std::map<long, App::Color>& NodeColorMap)
553-
{
554-
long endId = (--NodeColorMap.end())->first;
555-
556-
std::vector<App::Color> colorVec(endId + 1, App::Color(0, 1, 0));
557-
for (const auto& it : NodeColorMap) {
558-
colorVec[it.first] = it.second;
559-
}
560-
561-
setColorByNodeIdHelper(colorVec);
562-
}
563-
void ViewProviderFemMesh::setColorByNodeId(const std::vector<long>& NodeIds,
564-
const std::vector<App::Color>& NodeColors)
565-
{
566-
567-
long endId = *(std::max_element(NodeIds.begin(), NodeIds.end()));
568-
569-
std::vector<App::Color> colorVec(endId + 1, App::Color(0, 1, 0));
570-
long i = 0;
571-
for (std::vector<long>::const_iterator it = NodeIds.begin(); it != NodeIds.end(); ++it, i++) {
572-
colorVec[*it] = NodeColors[i];
573-
}
574-
575-
setColorByNodeIdHelper(colorVec);
576-
}
577-
578-
void ViewProviderFemMesh::setColorByNodeIdHelper(const std::vector<App::Color>& colorVec)
579-
{
580-
pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
581-
582-
// resizing and writing the color vector:
583-
pcShapeMaterial->diffuseColor.setNum(vNodeElementIdx.size());
584-
SbColor* colors = pcShapeMaterial->diffuseColor.startEditing();
585-
586-
long i = 0;
587-
for (std::vector<unsigned long>::const_iterator it = vNodeElementIdx.begin();
588-
it != vNodeElementIdx.end();
589-
++it, i++) {
590-
colors[i] = SbColor(colorVec[*it].r, colorVec[*it].g, colorVec[*it].b);
591-
}
592-
593-
pcShapeMaterial->diffuseColor.finishEditing();
594-
}
595-
596-
void ViewProviderFemMesh::resetColorByNodeId()
597-
{
598-
pcMatBinding->value = SoMaterialBinding::OVERALL;
599-
pcShapeMaterial->diffuseColor.setNum(0);
600-
const App::Color& c = ShapeAppearance.getDiffuseColor();
601-
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
602-
}
603-
604594
void ViewProviderFemMesh::setDisplacementByNodeId(const std::map<long, Base::Vector3d>& NodeDispMap)
605595
{
606596
long startId = NodeDispMap.begin()->first;
@@ -681,37 +671,164 @@ void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
681671
DisplacementFactor = factor;
682672
}
683673

684-
void ViewProviderFemMesh::setColorByElementId(const std::map<long, App::Color>& ElementColorMap)
674+
void ViewProviderFemMesh::setColorByNodeId(const std::vector<long>& NodeIds,
675+
const std::vector<App::Color>& NodeColors)
685676
{
686-
pcMatBinding->value = SoMaterialBinding::PER_FACE;
677+
long endId = *(std::max_element(NodeIds.begin(), NodeIds.end()));
678+
679+
std::vector<App::Color> colorVec(endId + 1, App::Color(0, 1, 0));
680+
long i = 0;
681+
for (std::vector<long>::const_iterator it = NodeIds.begin(); it != NodeIds.end(); ++it, i++) {
682+
colorVec[*it] = NodeColors[i];
683+
}
684+
685+
setColorByNodeIdHelper(colorVec);
686+
}
687+
688+
void ViewProviderFemMesh::setColorByNodeIdHelper(const std::vector<App::Color>& colorVec)
689+
{
690+
pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
687691

688692
// resizing and writing the color vector:
689-
pcShapeMaterial->diffuseColor.setNum(vFaceElementIdx.size());
693+
pcShapeMaterial->diffuseColor.setNum(vNodeElementIdx.size());
690694
SbColor* colors = pcShapeMaterial->diffuseColor.startEditing();
691695

692-
int i = 0;
693-
for (std::vector<unsigned long>::const_iterator it = vFaceElementIdx.begin();
694-
it != vFaceElementIdx.end();
696+
long i = 0;
697+
for (std::vector<unsigned long>::const_iterator it = vNodeElementIdx.begin();
698+
it != vNodeElementIdx.end();
695699
++it, i++) {
696-
unsigned long ElemIdx = ((*it) >> 3);
697-
const std::map<long, App::Color>::const_iterator pos = ElementColorMap.find(ElemIdx);
698-
if (pos == ElementColorMap.end()) {
699-
colors[i] = SbColor(0, 1, 0);
700-
}
701-
else {
702-
colors[i] = SbColor(pos->second.r, pos->second.g, pos->second.b);
700+
colors[i] = SbColor(colorVec[*it].r, colorVec[*it].g, colorVec[*it].b);
701+
}
702+
703+
pcShapeMaterial->diffuseColor.finishEditing();
704+
}
705+
706+
void ViewProviderFemMesh::resetColorByNodeId()
707+
{
708+
const App::Color& c = ShapeAppearance.getDiffuseColor();
709+
NodeColorArray.setValue(c);
710+
}
711+
712+
void ViewProviderFemMesh::setColorByNodeId(
713+
const std::map<std::vector<long>, App::Color>& elemColorMap)
714+
{
715+
setColorByIdHelper(elemColorMap, vNodeElementIdx, 0, NodeColorArray);
716+
}
717+
718+
void ViewProviderFemMesh::setColorByElementId(
719+
const std::map<std::vector<long>, App::Color>& elemColorMap)
720+
{
721+
setColorByIdHelper(elemColorMap, vFaceElementIdx, 3, ElementColorArray);
722+
}
723+
724+
void ViewProviderFemMesh::setColorByIdHelper(
725+
const std::map<std::vector<long>, App::Color>& elemColorMap,
726+
const std::vector<unsigned long>& vElementIdx,
727+
int rShift,
728+
App::PropertyColorList& prop)
729+
{
730+
std::vector<App::Color> vecColor(vElementIdx.size());
731+
std::map<long, const App::Color*> colorMap;
732+
for (const auto& m : elemColorMap) {
733+
for (long i : m.first) {
734+
colorMap[i] = &m.second;
703735
}
704736
}
705737

738+
App::Color baseDif = ShapeAppearance.getDiffuseColor();
739+
int i = 0;
740+
for (std::vector<unsigned long>::const_iterator it = vElementIdx.begin();
741+
it != vElementIdx.end();
742+
++it, i++) {
743+
unsigned long ElemIdx = ((*it) >> rShift);
744+
const std::map<long, const App::Color*>::const_iterator pos = colorMap.find(ElemIdx);
745+
printf("index: %lu\n", ElemIdx);
746+
vecColor[i] = pos == colorMap.end() ? baseDif : *pos->second;
747+
}
748+
749+
prop.setValue(vecColor);
750+
}
751+
752+
void ViewProviderFemMesh::setMaterialByColorArray(
753+
const App::PropertyColorList* prop,
754+
const std::vector<unsigned long>& vElementIdx) const
755+
{
756+
const App::Material& baseMat = ShapeAppearance[0];
757+
App::Color baseDif = baseMat.diffuseColor;
758+
App::Color baseAmb = baseMat.ambientColor;
759+
App::Color baseSpe = baseMat.specularColor;
760+
App::Color baseEmi = baseMat.emissiveColor;
761+
float baseShi = baseMat.shininess;
762+
float baseTra = baseMat.transparency;
763+
764+
// resizing and writing the color vector:
765+
std::vector<App::Color> vecColor = prop->getValue();
766+
printf("vecSize0: %zu\n", vecColor.size());
767+
size_t elemSize = vElementIdx.size();
768+
if (vecColor.size() == 1) {
769+
pcMatBinding->value = SoMaterialBinding::OVERALL;
770+
pcShapeMaterial->diffuseColor.setNum(0);
771+
pcShapeMaterial->ambientColor.setNum(0);
772+
pcShapeMaterial->specularColor.setNum(0);
773+
pcShapeMaterial->emissiveColor.setNum(0);
774+
pcShapeMaterial->diffuseColor.setValue(vecColor[0].r, vecColor[0].g, vecColor[0].b);
775+
pcShapeMaterial->ambientColor.setValue(baseAmb.r, baseAmb.g, baseAmb.b);
776+
pcShapeMaterial->specularColor.setValue(baseSpe.r, baseSpe.g, baseSpe.b);
777+
pcShapeMaterial->emissiveColor.setValue(baseEmi.r, baseEmi.g, baseEmi.b);
778+
pcShapeMaterial->shininess.setValue(baseShi);
779+
pcShapeMaterial->transparency.setValue(baseTra);
780+
781+
return;
782+
}
783+
784+
if (prop == &ElementColorArray) {
785+
pcMatBinding->value = SoMaterialBinding::PER_FACE;
786+
}
787+
else if (prop == &NodeColorArray) {
788+
pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
789+
}
790+
791+
pcShapeMaterial->diffuseColor.setNum(elemSize);
792+
SbColor* diffuse = pcShapeMaterial->diffuseColor.startEditing();
793+
pcShapeMaterial->ambientColor.setNum(elemSize);
794+
SbColor* ambient = pcShapeMaterial->ambientColor.startEditing();
795+
pcShapeMaterial->specularColor.setNum(elemSize);
796+
SbColor* specular = pcShapeMaterial->specularColor.startEditing();
797+
pcShapeMaterial->emissiveColor.setNum(elemSize);
798+
SbColor* emissive = pcShapeMaterial->emissiveColor.startEditing();
799+
pcShapeMaterial->shininess.setNum(elemSize);
800+
float* shininess = pcShapeMaterial->shininess.startEditing();
801+
pcShapeMaterial->transparency.setNum(elemSize);
802+
float* transparency = pcShapeMaterial->transparency.startEditing();
803+
804+
printf("vecSize: %zu\n", vecColor.size());
805+
printf("elemSize: %zu\n", elemSize);
806+
807+
vecColor.resize(elemSize, baseDif);
808+
809+
int i = 0;
810+
for (const App::Color& c : vecColor) {
811+
diffuse[i] = SbColor(c.r, c.g, c.b);
812+
ambient[i] = SbColor(baseAmb.r, baseAmb.g, baseAmb.b);
813+
specular[i] = SbColor(baseSpe.r, baseSpe.g, baseSpe.b);
814+
emissive[i] = SbColor(baseEmi.r, baseEmi.g, baseEmi.b);
815+
shininess[i] = baseShi;
816+
transparency[i] = baseTra;
817+
++i;
818+
}
819+
706820
pcShapeMaterial->diffuseColor.finishEditing();
821+
pcShapeMaterial->ambientColor.finishEditing();
822+
pcShapeMaterial->specularColor.finishEditing();
823+
pcShapeMaterial->emissiveColor.finishEditing();
824+
pcShapeMaterial->shininess.finishEditing();
825+
pcShapeMaterial->transparency.finishEditing();
707826
}
708827

709828
void ViewProviderFemMesh::resetColorByElementId()
710829
{
711-
pcMatBinding->value = SoMaterialBinding::OVERALL;
712-
pcShapeMaterial->diffuseColor.setNum(0);
713830
const App::Color& c = ShapeAppearance.getDiffuseColor();
714-
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
831+
ElementColorArray.setValue(c);
715832
}
716833

717834
// ----------------------------------------------------------------------------

src/Mod/Fem/Gui/ViewProviderFemMesh.h

+14-3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ class FemGuiExport ViewProviderFemMesh: public Gui::ViewProviderGeometryObject
7373
App::PropertyBool BackfaceCulling;
7474
App::PropertyBool ShowInner;
7575
App::PropertyInteger MaxFacesShowInner;
76+
App::PropertyEnumeration ColorMode;
77+
App::PropertyColorList NodeColorArray;
78+
App::PropertyColorList ElementColorArray;
7679

7780
void attach(App::DocumentObject* pcObject) override;
7881
void setDisplayMode(const char* ModeName) override;
@@ -110,7 +113,7 @@ class FemGuiExport ViewProviderFemMesh: public Gui::ViewProviderGeometryObject
110113
//@{
111114

112115
/// set the color for each node
113-
void setColorByNodeId(const std::map<long, App::Color>& NodeColorMap);
116+
void setColorByNodeId(const std::map<std::vector<long>, App::Color>& NodeColorMap);
114117
void setColorByNodeId(const std::vector<long>& NodeIds,
115118
const std::vector<App::Color>& NodeColors);
116119

@@ -125,9 +128,10 @@ class FemGuiExport ViewProviderFemMesh: public Gui::ViewProviderGeometryObject
125128
/// reaply the node displacement with a certain factor and do a redraw
126129
void applyDisplacementToNodes(double factor);
127130
/// set the color for each element
128-
void setColorByElementId(const std::map<long, App::Color>& ElementColorMap);
131+
void setColorByElementId(const std::map<std::vector<long>, App::Color>& ElementColorMap);
129132
/// reset the view of the element colors
130133
void resetColorByElementId();
134+
void setMaterialByElement();
131135
//@}
132136

133137
const std::vector<unsigned long>& getVisibleElementFaces() const
@@ -139,6 +143,7 @@ class FemGuiExport ViewProviderFemMesh: public Gui::ViewProviderGeometryObject
139143

140144
private:
141145
static App::PropertyFloatConstraint::Constraints floatRange;
146+
static const char* colorModeEnum[];
142147

143148
Py::Object PythonObject;
144149

@@ -148,11 +153,17 @@ class FemGuiExport ViewProviderFemMesh: public Gui::ViewProviderGeometryObject
148153

149154
void setColorByNodeIdHelper(const std::vector<App::Color>&);
150155
void setDisplacementByNodeIdHelper(const std::vector<Base::Vector3d>& DispVector, long startId);
156+
void setColorByIdHelper(const std::map<std::vector<long>, App::Color>& elemColorMap,
157+
const std::vector<unsigned long>& vElementIdx,
158+
int rShift,
159+
App::PropertyColorList& prop);
160+
void setMaterialByColorArray(const App::PropertyColorList* prop,
161+
const std::vector<unsigned long>& vElementIdx) const;
162+
151163
/// index of elements to their triangles
152164
std::vector<unsigned long> vFaceElementIdx;
153165
std::vector<unsigned long> vNodeElementIdx;
154166
std::vector<unsigned long> vHighlightedIdx;
155-
156167
std::vector<Base::Vector3d> DisplacementVector;
157168
double DisplacementFactor;
158169

0 commit comments

Comments
 (0)