@@ -186,6 +186,8 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject)
186
186
187
187
App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0 , 64.0 , 1.0 };
188
188
189
+ const char * ViewProviderFemMesh::colorModeEnum[] = {" Overall" , " ByElement" , " ByNode" , nullptr };
190
+
189
191
ViewProviderFemMesh::ViewProviderFemMesh ()
190
192
{
191
193
sPixmap = " fem-femmesh-from-shape" ;
@@ -202,6 +204,23 @@ ViewProviderFemMesh::ViewProviderFemMesh()
202
204
ADD_PROPERTY (ShowInner, (false ));
203
205
ADD_PROPERTY (MaxFacesShowInner, (50000 ));
204
206
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);
205
224
onlyEdges = false ;
206
225
207
226
pcDrawStyle = new SoDrawStyle ();
@@ -380,6 +399,16 @@ void ViewProviderFemMesh::updateData(const App::Property* prop)
380
399
381
400
void ViewProviderFemMesh::onChanged (const App::Property* prop)
382
401
{
402
+ auto matchTransparency = [&]() {
403
+ if (getObject () && getObject ()->testStatus (App::ObjectStatus::TouchOnColorChange)) {
404
+ getObject ()->touch (true );
405
+ }
406
+ long value = static_cast <long >(100 * ShapeAppearance.getTransparency () + 0.5 );
407
+ if (value != Transparency.getValue ()) {
408
+ Transparency.setValue (value);
409
+ }
410
+ };
411
+
383
412
if (prop == &PointSize) {
384
413
pcPointStyle->pointSize = PointSize.getValue ();
385
414
}
@@ -413,6 +442,31 @@ void ViewProviderFemMesh::onChanged(const App::Property* prop)
413
442
else if (prop == &LineWidth) {
414
443
pcDrawStyle->lineWidth = LineWidth.getValue ();
415
444
}
445
+ else if (prop == &ColorMode) {
446
+ switch (ColorMode.getValue ()) {
447
+ case 1 : // ByElement
448
+ setMaterialByColorArray (&ElementColorArray, vFaceElementIdx);
449
+ break ;
450
+ case 2 : // ByNode
451
+ setMaterialByColorArray (&NodeColorArray, vNodeElementIdx);
452
+ break ;
453
+ default : // Overall
454
+ setMaterialOverall ();
455
+ }
456
+ }
457
+ else if (prop == &ShapeAppearance && ColorMode.getValue () == 0 ) {
458
+ matchTransparency ();
459
+ setMaterialOverall ();
460
+ }
461
+ else if ((prop == &ElementColorArray || prop == &ShapeAppearance)
462
+ && ColorMode.getValue () == 1 ) {
463
+ matchTransparency ();
464
+ setMaterialByColorArray (&ElementColorArray, vFaceElementIdx);
465
+ }
466
+ else if ((prop == &NodeColorArray || prop == &ShapeAppearance) && ColorMode.getValue () == 2 ) {
467
+ matchTransparency ();
468
+ setMaterialByColorArray (&NodeColorArray, vNodeElementIdx);
469
+ }
416
470
else {
417
471
ViewProviderGeometryObject::onChanged (prop);
418
472
}
@@ -549,58 +603,6 @@ PyObject* ViewProviderFemMesh::getPyObject()
549
603
return Py::new_reference_to (PythonObject);
550
604
}
551
605
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
-
604
606
void ViewProviderFemMesh::setDisplacementByNodeId (const std::map<long , Base::Vector3d>& NodeDispMap)
605
607
{
606
608
long startId = NodeDispMap.begin ()->first ;
@@ -681,37 +683,192 @@ void ViewProviderFemMesh::applyDisplacementToNodes(double factor)
681
683
DisplacementFactor = factor;
682
684
}
683
685
684
- void ViewProviderFemMesh::setColorByElementId (const std::map<long , App::Color>& ElementColorMap)
686
+ void ViewProviderFemMesh::setColorByNodeId (const std::vector<long >& NodeIds,
687
+ const std::vector<App::Color>& NodeColors)
688
+ {
689
+ long endId = *(std::max_element (NodeIds.begin (), NodeIds.end ()));
690
+
691
+ std::vector<App::Color> colorVec (endId + 1 , App::Color (0 , 1 , 0 ));
692
+ long i = 0 ;
693
+ for (std::vector<long >::const_iterator it = NodeIds.begin (); it != NodeIds.end (); ++it, i++) {
694
+ colorVec[*it] = NodeColors[i];
695
+ }
696
+
697
+ setColorByNodeIdHelper (colorVec);
698
+ }
699
+
700
+ void ViewProviderFemMesh::setColorByNodeIdHelper (const std::vector<App::Color>& colorVec)
685
701
{
686
- pcMatBinding->value = SoMaterialBinding::PER_FACE ;
702
+ pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED ;
687
703
688
704
// resizing and writing the color vector:
689
- pcShapeMaterial->diffuseColor .setNum (vFaceElementIdx .size ());
705
+ pcShapeMaterial->diffuseColor .setNum (vNodeElementIdx .size ());
690
706
SbColor* colors = pcShapeMaterial->diffuseColor .startEditing ();
691
707
692
- int i = 0 ;
693
- for (std::vector<unsigned long >::const_iterator it = vFaceElementIdx .begin ();
694
- it != vFaceElementIdx .end ();
708
+ long i = 0 ;
709
+ for (std::vector<unsigned long >::const_iterator it = vNodeElementIdx .begin ();
710
+ it != vNodeElementIdx .end ();
695
711
++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
- }
712
+ colors[i] = SbColor (colorVec[*it].r , colorVec[*it].g , colorVec[*it].b );
704
713
}
705
714
706
715
pcShapeMaterial->diffuseColor .finishEditing ();
707
716
}
708
717
709
- void ViewProviderFemMesh::resetColorByElementId ()
718
+ void ViewProviderFemMesh::resetColorByNodeId ()
719
+ {
720
+ const App::Color& c = ShapeAppearance.getDiffuseColor ();
721
+ NodeColorArray.setValue (c);
722
+ }
723
+
724
+ void ViewProviderFemMesh::setColorByNodeId (
725
+ const std::map<std::vector<long >, App::Color>& elemColorMap)
710
726
{
727
+ setColorByIdHelper (elemColorMap, vNodeElementIdx, 0 , NodeColorArray);
728
+ }
729
+
730
+ void ViewProviderFemMesh::setColorByElementId (
731
+ const std::map<std::vector<long >, App::Color>& elemColorMap)
732
+ {
733
+ setColorByIdHelper (elemColorMap, vFaceElementIdx, 3 , ElementColorArray);
734
+ }
735
+
736
+ void ViewProviderFemMesh::setColorByIdHelper (
737
+ const std::map<std::vector<long >, App::Color>& elemColorMap,
738
+ const std::vector<unsigned long >& vElementIdx,
739
+ int rShift,
740
+ App::PropertyColorList& prop)
741
+ {
742
+ std::vector<App::Color> vecColor (vElementIdx.size ());
743
+ std::map<long , const App::Color*> colorMap;
744
+ for (const auto & m : elemColorMap) {
745
+ for (long i : m.first ) {
746
+ colorMap[i] = &m.second ;
747
+ }
748
+ }
749
+
750
+ App::Color baseDif = ShapeAppearance.getDiffuseColor ();
751
+ int i = 0 ;
752
+ for (std::vector<unsigned long >::const_iterator it = vElementIdx.begin ();
753
+ it != vElementIdx.end ();
754
+ ++it, i++) {
755
+ unsigned long ElemIdx = ((*it) >> rShift);
756
+ const std::map<long , const App::Color*>::const_iterator pos = colorMap.find (ElemIdx);
757
+ vecColor[i] = pos == colorMap.end () ? baseDif : *pos->second ;
758
+ }
759
+
760
+ prop.setValue (vecColor);
761
+ }
762
+
763
+ void ViewProviderFemMesh::setMaterialOverall () const
764
+ {
765
+ const App::Material& mat = ShapeAppearance[0 ];
766
+ App::Color baseDif = mat.diffuseColor ;
767
+ App::Color baseAmb = mat.ambientColor ;
768
+ App::Color baseSpe = mat.specularColor ;
769
+ App::Color baseEmi = mat.emissiveColor ;
770
+ float baseShi = mat.shininess ;
771
+ float baseTra = mat.transparency ;
772
+
711
773
pcMatBinding->value = SoMaterialBinding::OVERALL;
712
774
pcShapeMaterial->diffuseColor .setNum (0 );
775
+ pcShapeMaterial->ambientColor .setNum (0 );
776
+ pcShapeMaterial->specularColor .setNum (0 );
777
+ pcShapeMaterial->emissiveColor .setNum (0 );
778
+ pcShapeMaterial->shininess .setNum (0 );
779
+ pcShapeMaterial->transparency .setNum (0 );
780
+ pcShapeMaterial->diffuseColor .setValue (baseDif.r , baseDif.g , baseDif.b );
781
+ pcShapeMaterial->ambientColor .setValue (baseAmb.r , baseAmb.g , baseAmb.b );
782
+ pcShapeMaterial->specularColor .setValue (baseSpe.r , baseSpe.g , baseSpe.b );
783
+ pcShapeMaterial->emissiveColor .setValue (baseEmi.r , baseEmi.g , baseEmi.b );
784
+ pcShapeMaterial->shininess .setValue (baseShi);
785
+ pcShapeMaterial->transparency .setValue (baseTra);
786
+
787
+ pcFaces->touch ();
788
+
789
+ return ;
790
+ }
791
+
792
+ void ViewProviderFemMesh::setMaterialByColorArray (
793
+ const App::PropertyColorList* prop,
794
+ const std::vector<unsigned long >& vElementIdx) const
795
+ {
796
+ const App::Material& baseMat = ShapeAppearance[0 ];
797
+ App::Color baseDif = baseMat.diffuseColor ;
798
+ App::Color baseAmb = baseMat.ambientColor ;
799
+ App::Color baseSpe = baseMat.specularColor ;
800
+ App::Color baseEmi = baseMat.emissiveColor ;
801
+ float baseShi = baseMat.shininess ;
802
+ float baseTra = baseMat.transparency ;
803
+
804
+ // resizing and writing the color vector:
805
+ std::vector<App::Color> vecColor = prop->getValue ();
806
+ size_t elemSize = vElementIdx.size ();
807
+ if (vecColor.size () == 1 ) {
808
+ pcMatBinding->value = SoMaterialBinding::OVERALL;
809
+ pcShapeMaterial->diffuseColor .setNum (0 );
810
+ pcShapeMaterial->ambientColor .setNum (0 );
811
+ pcShapeMaterial->specularColor .setNum (0 );
812
+ pcShapeMaterial->emissiveColor .setNum (0 );
813
+ pcShapeMaterial->shininess .setNum (0 );
814
+ pcShapeMaterial->transparency .setNum (0 );
815
+ pcShapeMaterial->diffuseColor .setValue (vecColor[0 ].r , vecColor[0 ].g , vecColor[0 ].b );
816
+ pcShapeMaterial->ambientColor .setValue (baseAmb.r , baseAmb.g , baseAmb.b );
817
+ pcShapeMaterial->specularColor .setValue (baseSpe.r , baseSpe.g , baseSpe.b );
818
+ pcShapeMaterial->emissiveColor .setValue (baseEmi.r , baseEmi.g , baseEmi.b );
819
+ pcShapeMaterial->shininess .setValue (baseShi);
820
+ pcShapeMaterial->transparency .setValue (baseTra);
821
+
822
+ return ;
823
+ }
824
+
825
+ if (prop == &ElementColorArray) {
826
+ pcMatBinding->value = SoMaterialBinding::PER_FACE;
827
+ }
828
+ else if (prop == &NodeColorArray) {
829
+ pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
830
+ }
831
+
832
+ pcShapeMaterial->diffuseColor .setNum (elemSize);
833
+ SbColor* diffuse = pcShapeMaterial->diffuseColor .startEditing ();
834
+ pcShapeMaterial->ambientColor .setNum (elemSize);
835
+ SbColor* ambient = pcShapeMaterial->ambientColor .startEditing ();
836
+ pcShapeMaterial->specularColor .setNum (elemSize);
837
+ SbColor* specular = pcShapeMaterial->specularColor .startEditing ();
838
+ pcShapeMaterial->emissiveColor .setNum (elemSize);
839
+ SbColor* emissive = pcShapeMaterial->emissiveColor .startEditing ();
840
+ pcShapeMaterial->shininess .setNum (elemSize);
841
+ float * shininess = pcShapeMaterial->shininess .startEditing ();
842
+ pcShapeMaterial->transparency .setNum (elemSize);
843
+ float * transparency = pcShapeMaterial->transparency .startEditing ();
844
+
845
+ vecColor.resize (elemSize, baseDif);
846
+
847
+ int i = 0 ;
848
+ for (const App::Color& c : vecColor) {
849
+ diffuse[i] = SbColor (c.r , c.g , c.b );
850
+ ambient[i] = SbColor (baseAmb.r , baseAmb.g , baseAmb.b );
851
+ specular[i] = SbColor (baseSpe.r , baseSpe.g , baseSpe.b );
852
+ emissive[i] = SbColor (baseEmi.r , baseEmi.g , baseEmi.b );
853
+ shininess[i] = baseShi;
854
+ transparency[i] = baseTra;
855
+ ++i;
856
+ }
857
+
858
+ pcShapeMaterial->diffuseColor .finishEditing ();
859
+ pcShapeMaterial->ambientColor .finishEditing ();
860
+ pcShapeMaterial->specularColor .finishEditing ();
861
+ pcShapeMaterial->emissiveColor .finishEditing ();
862
+ pcShapeMaterial->shininess .finishEditing ();
863
+ pcShapeMaterial->transparency .finishEditing ();
864
+
865
+ pcFaces->touch ();
866
+ }
867
+
868
+ void ViewProviderFemMesh::resetColorByElementId ()
869
+ {
713
870
const App::Color& c = ShapeAppearance.getDiffuseColor ();
714
- pcShapeMaterial-> diffuseColor .setValue (c. r , c. g , c. b );
871
+ ElementColorArray .setValue (c);
715
872
}
716
873
717
874
// ----------------------------------------------------------------------------
0 commit comments