DzProperty::currentValueChanged() not working?

pcicconepciccone Posts: 634
edited December 1969 in Daz SDK Developer Discussion

Hi.

I need to be notified when a material changed in Studio. For example, when the user applies a skin to V4 or Genesis. In this post: http://www.daz3d.com/forums/discussion/36541/ it was suggested to use DzProperty::currentValueChanged(), which I am doing now.
The code that I use is something like this:

    
ReDSMaterialListIterator i(matList);
while( i.hasNext() ) {
  DzMaterial* mat = i.next();
  // Scan the list of properties and monitor their changes
  auto i = mat->propertyListIterator();
  while( i.hasNext() ) {
    auto prop = i.next();
    // Get notifications when the material changes
    connect(prop, SIGNAL(currentValueChanged()), this, SLOT(watchMaterial()));
  }
}

Matlist is simply a QList collected by a previous step.
This works for some materials and it doesn't for others. More precisely, while the list of properties monitored for something like V4's 1_SkinFace is:

DS mat monitored: 1_SkinFace
  Diffuse Color
  Diffuse Strength
  Glossiness
  Specular Color
  Specular Strength
  Multiply Specular Through Opacity
  Ambient Color
  Ambient Strength
  Opacity Strength
  Bump Strength
  Negative Bump
  Positive Bump
  Displacement Strength
  Minimum Displacement
  Maximum Displacement
  Normal Map
  Reflection Color
  Reflection Strength
  Refraction Color
  Refraction Strength
  Index of Refraction
  Horizontal Tiles
  Horizontal Offset
  Vertical Tiles
  Vertical Offset
  Lighting Model
  UV Set
  Smooth On
  Smooth Angle
  Render Priority
  Propagate Priority
  Follow Blend

For some skins the slot receives notifications only for a property named "UV Set" for 1_SkinFace. The signal for Diffuse and other properties modified by the skin, a pz2 file, is never received. This is with a products called "Ireland" by Vyktohria. Same experience with SAV Maraki for Dawn. The skins are applied to V4 or Dawn. I can see the difference in the Surfaces tab.

Is there some missing step that needs to be performed to receive notification for all properties in the loop?

Thanks in advance.

Comments

  • pcicconepciccone Posts: 634
    edited December 1969

    After some more testing I noticed that hand-changing the material in the Surfaces tab triggers the slot correctly.

    Applying a material preset calls the watchMaterial() slot for all materials but the vast majority of the calls are for a "UV Set" property. The slot tries to find the owner of the property but it fails for most properties in this way:

    void Reality_DS::watchMaterial() {
      if (dzApp->isClosing()) {
        return;
      }
      auto prop = qobject_cast(QObject::sender());
      RE_LOG_INFO() << "MAT: " 
                    << prop->getOwner()->getName().toStdString()
                    << " " << prop->getName().toStdString();
      auto propOwner = prop->getOwner();
      if (propOwner->inherits("DzMaterial")) {      
        auto mat = qobject_cast(propOwner);
        auto i = mat->shapeListIterator();
        while( i.hasNext() ) {
          auto node = i.next()->getNode();
          if (node) {
            QString objID = ReGUID::getGUID(node);
            QString matName = mat->getName();
            QString key = QString("%1::%2").arg(objID).arg(matName);
            materialRefreshTable[key] = mat;
          }
        }
      }
    }
    

    Apparently, the mat->shapeListIterator() returns an empty list, because no updates are queued in the materialRefreshTable container.
    I hope this gives you an idea of what's happening. It seems that it's very hard for a plugin to monitor material changes consistently. If you have an alternative method that will be greatly appreciated.

    Thank you.

  • pcicconepciccone Posts: 634
    edited May 2014

    More testing. When using V4 with PZ2 files every material preset works as expected.

    Post edited by pciccone on
  • pcicconepciccone Posts: 634
    edited December 1969

    I have to rectify my previous observation. As initially reported, the Ireland skin fails to set all materials. It triggers the update for:

    - 5_Lacrimal
    - 4_Teeth
    - 6_Eyelash
    - 4_InnerMouth
    - 5_Sclera
    - 5_Pupil
    - 4_Gums
    - 1_Eyebrow
    - 7_EyeSurface
    - 5_Iris
    - 4_Tongue
    - 5_Cornea
    - 7_Tear

    So, it seems that, in this case, most non-skin materials are triggers but all the skin-related mats don't. The preset is also a pz2.

    Hope this helps.

  • dtammdtamm Posts: 126
    edited December 1969

    A material preset can modify properties as you see, but a preset can also replace materials entirely.

    So, you will want to listen for some combination of the following signals on DzShape:
    void materialAdded( DzMaterial *mat );
    void materialRemoved( DzMaterial *mat );
    void materialListChanged();

  • pcicconepciccone Posts: 634
    edited December 1969

    dtamm said:
    A material preset can modify properties as you see, but a preset can also replace materials entirely.

    So, you will want to listen for some combination of the following signals on DzShape:
    void materialAdded( DzMaterial *mat );
    void materialRemoved( DzMaterial *mat );
    void materialListChanged();


    I'll try that. Thank you.
    So, you are saying that, even though the material itself will be the same, say 1_SkinFace, the preset might actually cause the shader to be deleted and then replaced with a shader that has the same name and properties but that it's created from scratch. Am I understanding this correctly?
  • dtammdtamm Posts: 126
    edited December 1969

    Pret-A-3D said:
    dtamm said:
    A material preset can modify properties as you see, but a preset can also replace materials entirely.

    So, you will want to listen for some combination of the following signals on DzShape:
    void materialAdded( DzMaterial *mat );
    void materialRemoved( DzMaterial *mat );
    void materialListChanged();


    I'll try that. Thank you.
    So, you are saying that, even though the material itself will be the same, say 1_SkinFace, the preset might actually cause the shader to be deleted and then replaced with a shader that has the same name and properties but that it's created from scratch. Am I understanding this correctly?

    The name of the material group will still be 1_SkinFace. The name is determined by the geometry, in the case for V4 the name is in the obj file. The material itself, denoted by DzMaterial* can be entirely different after a material preset is applied. If the current material in the 1_SkinFace group is a DzDefaultMaterial and the preset wants DzShaderMaterial, then the current material that corresponds to 1_SkinFace will be removed and then replaced with a different material. In which case you would want to disconnect from the removed material and connect up to the new material.

  • pcicconepciccone Posts: 634
    edited December 1969

    Thank you for the information.
    Unfortunately it seems that there are cases that are not so cut and dry.
    For example, the "Ireland" skin for V4 works OK when applying the full skin to V4. Reality gets the notifications.
    I added slots for: materialChanged(), materialRemoved(DzMaterial*), materialAdded(DzMaterial*), and materialListChanged() of each shape in the figure.

    When applying some pz2 files for makeup or lips no slot is called.
    Is there a way of monitoring what signals are called by Studio during a certain operation? Any way of installing a global signal monitor?

    Thanks in advance.

  • pcicconepciccone Posts: 634
    edited December 1969

    I forgot to mention that I also monitor the currentValueChanged() signal of every property of the materials and don't get any notification in the case described above.

  • pcicconepciccone Posts: 634
    edited December 1969

    One last detail. The pz2 file has an associated dsa file that is executed by Studio as expected.

  • pcicconepciccone Posts: 634
    edited December 1969

    I have resolved it.
    The DZShape::materialListChanged() in fact notifies that the materials have been changed and old materials possibly deleted. Although I had a slot assigned to the materialRemoved(DzMaterial*) method, it was never called. Instead, the materialListChanged() signal is what needs to be monitored. Once I receive that signal it means that the program has to connect to the new materials. In that way everything works as expected and very quickly too.

    Cheers.

Sign In or Register to comment.