Skip to content

Commit 5289bb5

Browse files
committed
Fem: Mesh color
1 parent ed77603 commit 5289bb5

File tree

3 files changed

+258
-111
lines changed

3 files changed

+258
-111
lines changed

src/Mod/Fem/Gui/ViewProviderFemMesh.cpp

+211-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+
ADD_PROPERTY_TYPE(NodeColorArray,
213+
(PointColor.getValue()),
214+
"Object Style",
215+
App::Prop_Hidden,
216+
"Node diffuse color array");
217+
ADD_PROPERTY_TYPE(ElementColorArray,
218+
(ShapeAppearance.getDiffuseColor()),
219+
"Object Style",
220+
App::Prop_Hidden,
221+
"Node diffuse color array");
222+
223+
ColorMode.setEnums(colorModeEnum);
205224
onlyEdges = false;
206225

207226
pcDrawStyle = new SoDrawStyle();
@@ -413,6 +432,27 @@ 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+
setMaterialOverall();
445+
}
446+
}
447+
else if (prop == &ShapeAppearance && ColorMode.getValue() == 0) {
448+
setMaterialOverall();
449+
}
450+
else if ((prop == &ElementColorArray || prop == &ShapeAppearance) && ColorMode.getValue() == 1) {
451+
setMaterialByColorArray(&ElementColorArray, vFaceElementIdx);
452+
}
453+
else if ((prop == &NodeColorArray || prop == &ShapeAppearance) && ColorMode.getValue() == 2) {
454+
setMaterialByColorArray(&NodeColorArray, vNodeElementIdx);
455+
}
416456
else {
417457
ViewProviderGeometryObject::onChanged(prop);
418458
}
@@ -549,58 +589,6 @@ PyObject* ViewProviderFemMesh::getPyObject()
549589
return Py::new_reference_to(PythonObject);
550590
}
551591

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-
604592
void ViewProviderFemMesh::setDisplacementByNodeId(const std::map<long, Base::Vector3d>& NodeDispMap)
605593
{
606594
long startId = NodeDispMap.begin()->first;
@@ -681,37 +669,192 @@ void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
681669
DisplacementFactor = factor;
682670
}
683671

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

688690
// resizing and writing the color vector:
689-
pcShapeMaterial->diffuseColor.setNum(vFaceElementIdx.size());
691+
pcShapeMaterial->diffuseColor.setNum(vNodeElementIdx.size());
690692
SbColor* colors = pcShapeMaterial->diffuseColor.startEditing();
691693

692-
int i = 0;
693-
for (std::vector<unsigned long>::const_iterator it = vFaceElementIdx.begin();
694-
it != vFaceElementIdx.end();
694+
long i = 0;
695+
for (std::vector<unsigned long>::const_iterator it = vNodeElementIdx.begin();
696+
it != vNodeElementIdx.end();
695697
++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);
703-
}
698+
colors[i] = SbColor(colorVec[*it].r, colorVec[*it].g, colorVec[*it].b);
704699
}
705700

706701
pcShapeMaterial->diffuseColor.finishEditing();
707702
}
708703

709-
void ViewProviderFemMesh::resetColorByElementId()
704+
void ViewProviderFemMesh::resetColorByNodeId()
705+
{
706+
const App::Color& c = ShapeAppearance.getDiffuseColor();
707+
NodeColorArray.setValue(c);
708+
}
709+
710+
void ViewProviderFemMesh::setColorByNodeId(
711+
const std::map<std::vector<long>, App::Color>& elemColorMap)
710712
{
713+
setColorByIdHelper(elemColorMap, vNodeElementIdx, 0, NodeColorArray);
714+
}
715+
716+
void ViewProviderFemMesh::setColorByElementId(
717+
const std::map<std::vector<long>, App::Color>& elemColorMap)
718+
{
719+
setColorByIdHelper(elemColorMap, vFaceElementIdx, 3, ElementColorArray);
720+
}
721+
722+
void ViewProviderFemMesh::setColorByIdHelper(
723+
const std::map<std::vector<long>, App::Color>& elemColorMap,
724+
const std::vector<unsigned long>& vElementIdx,
725+
int rShift,
726+
App::PropertyColorList& prop)
727+
{
728+
std::vector<App::Color> vecColor(vElementIdx.size());
729+
std::map<long, const App::Color*> colorMap;
730+
for (const auto& m : elemColorMap) {
731+
for (long i : m.first) {
732+
colorMap[i] = &m.second;
733+
}
734+
}
735+
736+
App::Color baseDif = ShapeAppearance.getDiffuseColor();
737+
int i = 0;
738+
for (std::vector<unsigned long>::const_iterator it = vElementIdx.begin();
739+
it != vElementIdx.end();
740+
++it, i++) {
741+
unsigned long ElemIdx = ((*it) >> rShift);
742+
const std::map<long, const App::Color*>::const_iterator pos = colorMap.find(ElemIdx);
743+
vecColor[i] = pos == colorMap.end() ? baseDif : *pos->second;
744+
}
745+
746+
prop.setValue(vecColor);
747+
}
748+
749+
void ViewProviderFemMesh::setMaterialOverall() const
750+
{
751+
const App::Material& mat = ShapeAppearance[0];
752+
App::Color baseDif = mat.diffuseColor;
753+
App::Color baseAmb = mat.ambientColor;
754+
App::Color baseSpe = mat.specularColor;
755+
App::Color baseEmi = mat.emissiveColor;
756+
float baseShi = mat.shininess;
757+
float baseTra = mat.transparency;
758+
711759
pcMatBinding->value = SoMaterialBinding::OVERALL;
712760
pcShapeMaterial->diffuseColor.setNum(0);
761+
pcShapeMaterial->ambientColor.setNum(0);
762+
pcShapeMaterial->specularColor.setNum(0);
763+
pcShapeMaterial->emissiveColor.setNum(0);
764+
pcShapeMaterial->shininess.setNum(0);
765+
pcShapeMaterial->transparency.setNum(0);
766+
pcShapeMaterial->diffuseColor.setValue(baseDif.r, baseDif.g, baseDif.b);
767+
pcShapeMaterial->ambientColor.setValue(baseAmb.r, baseAmb.g, baseAmb.b);
768+
pcShapeMaterial->specularColor.setValue(baseSpe.r, baseSpe.g, baseSpe.b);
769+
pcShapeMaterial->emissiveColor.setValue(baseEmi.r, baseEmi.g, baseEmi.b);
770+
pcShapeMaterial->shininess.setValue(baseShi);
771+
pcShapeMaterial->transparency.setValue(baseTra);
772+
773+
pcFaces->touch();
774+
775+
return;
776+
}
777+
778+
void ViewProviderFemMesh::setMaterialByColorArray(
779+
const App::PropertyColorList* prop,
780+
const std::vector<unsigned long>& vElementIdx) const
781+
{
782+
const App::Material& baseMat = ShapeAppearance[0];
783+
App::Color baseDif = baseMat.diffuseColor;
784+
App::Color baseAmb = baseMat.ambientColor;
785+
App::Color baseSpe = baseMat.specularColor;
786+
App::Color baseEmi = baseMat.emissiveColor;
787+
float baseShi = baseMat.shininess;
788+
float baseTra = baseMat.transparency;
789+
790+
// resizing and writing the color vector:
791+
std::vector<App::Color> vecColor = prop->getValue();
792+
size_t elemSize = vElementIdx.size();
793+
if (vecColor.size() == 1) {
794+
pcMatBinding->value = SoMaterialBinding::OVERALL;
795+
pcShapeMaterial->diffuseColor.setNum(0);
796+
pcShapeMaterial->ambientColor.setNum(0);
797+
pcShapeMaterial->specularColor.setNum(0);
798+
pcShapeMaterial->emissiveColor.setNum(0);
799+
pcShapeMaterial->shininess.setNum(0);
800+
pcShapeMaterial->transparency.setNum(0);
801+
pcShapeMaterial->diffuseColor.setValue(vecColor[0].r, vecColor[0].g, vecColor[0].b);
802+
pcShapeMaterial->ambientColor.setValue(baseAmb.r, baseAmb.g, baseAmb.b);
803+
pcShapeMaterial->specularColor.setValue(baseSpe.r, baseSpe.g, baseSpe.b);
804+
pcShapeMaterial->emissiveColor.setValue(baseEmi.r, baseEmi.g, baseEmi.b);
805+
pcShapeMaterial->shininess.setValue(baseShi);
806+
pcShapeMaterial->transparency.setValue(baseTra);
807+
808+
return;
809+
}
810+
811+
if (prop == &ElementColorArray) {
812+
pcMatBinding->value = SoMaterialBinding::PER_FACE;
813+
}
814+
else if (prop == &NodeColorArray) {
815+
pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
816+
}
817+
818+
pcShapeMaterial->diffuseColor.setNum(elemSize);
819+
SbColor* diffuse = pcShapeMaterial->diffuseColor.startEditing();
820+
pcShapeMaterial->ambientColor.setNum(elemSize);
821+
SbColor* ambient = pcShapeMaterial->ambientColor.startEditing();
822+
pcShapeMaterial->specularColor.setNum(elemSize);
823+
SbColor* specular = pcShapeMaterial->specularColor.startEditing();
824+
pcShapeMaterial->emissiveColor.setNum(elemSize);
825+
SbColor* emissive = pcShapeMaterial->emissiveColor.startEditing();
826+
pcShapeMaterial->shininess.setNum(elemSize);
827+
float* shininess = pcShapeMaterial->shininess.startEditing();
828+
pcShapeMaterial->transparency.setNum(elemSize);
829+
float* transparency = pcShapeMaterial->transparency.startEditing();
830+
831+
vecColor.resize(elemSize, baseDif);
832+
833+
int i = 0;
834+
for (const App::Color& c : vecColor) {
835+
diffuse[i] = SbColor(c.r, c.g, c.b);
836+
ambient[i] = SbColor(baseAmb.r, baseAmb.g, baseAmb.b);
837+
specular[i] = SbColor(baseSpe.r, baseSpe.g, baseSpe.b);
838+
emissive[i] = SbColor(baseEmi.r, baseEmi.g, baseEmi.b);
839+
shininess[i] = baseShi;
840+
transparency[i] = baseTra;
841+
++i;
842+
}
843+
844+
pcShapeMaterial->diffuseColor.finishEditing();
845+
pcShapeMaterial->ambientColor.finishEditing();
846+
pcShapeMaterial->specularColor.finishEditing();
847+
pcShapeMaterial->emissiveColor.finishEditing();
848+
pcShapeMaterial->shininess.finishEditing();
849+
pcShapeMaterial->transparency.finishEditing();
850+
851+
pcFaces->touch();
852+
}
853+
854+
void ViewProviderFemMesh::resetColorByElementId()
855+
{
713856
const App::Color& c = ShapeAppearance.getDiffuseColor();
714-
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
857+
ElementColorArray.setValue(c);
715858
}
716859

717860
// ----------------------------------------------------------------------------

src/Mod/Fem/Gui/ViewProviderFemMesh.h

+15-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,18 @@ 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+
void setMaterialOverall() const;
163+
151164
/// index of elements to their triangles
152165
std::vector<unsigned long> vFaceElementIdx;
153166
std::vector<unsigned long> vNodeElementIdx;
154167
std::vector<unsigned long> vHighlightedIdx;
155-
156168
std::vector<Base::Vector3d> DisplacementVector;
157169
double DisplacementFactor;
158170

0 commit comments

Comments
 (0)