예제 #1
0
void MatMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
   {
   Interval valid = FOREVER;
   int id;
   pblock->GetValue(PB_MATID,t,id,valid); 
   id--;
   if (id<0) id = 0;
   if (id>0xffff) id = 0xffff;

   // For version 4 and later, we process patch meshes as they are and pass them on.  Earlier
   // versions converted to TriMeshes (done below).  For adding other new types of objects, add
   // them here!
#ifndef NO_PATCHES
   if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
      PatchObject *patchOb = (PatchObject *)os->obj;
      PatchMesh &pmesh = patchOb->GetPatchMesh(t);
      BOOL useSel = pmesh.selLevel >= PO_PATCH;

      for (int i=0; i<pmesh.getNumPatches(); i++) {
         if (!useSel || pmesh.patchSel[i]) {
            pmesh.setPatchMtlIndex(i,(MtlID)id);
            }
         }
      pmesh.InvalidateGeomCache();  // Do this because there isn't a topo cache in PatchMesh
                  
      patchOb->UpdateValidity(TOPO_CHAN_NUM,valid);      
      }
   else
#endif // NO_PATCHES
   // Process PolyObjects
   if(os->obj->IsSubClassOf(polyObjectClassID)) {
      PolyObject *polyOb = (PolyObject *)os->obj;
      MNMesh &mesh = polyOb->GetMesh();
      BOOL useSel = mesh.selLevel == MNM_SL_FACE;

      for (int i=0; i<mesh.numf; i++) {
         if (!useSel || mesh.f[i].GetFlag(MN_SEL)) {
            mesh.f[i].material = (MtlID)id;
         }
      }
      polyOb->UpdateValidity(TOPO_CHAN_NUM,valid);    
   }
   else  // If it's a TriObject, process it
   if(os->obj->IsSubClassOf(triObjectClassID)) {
      TriObject *triOb = (TriObject *)os->obj;
      DoMaterialSet(triOb, id);
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
      }
   else  // Fallback position: If it can convert to a TriObject, do it!
   if(os->obj->CanConvertToType(triObjectClassID)) {
      TriObject  *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);
      // Now stuff this into the pipeline!
      os->obj = triOb;

      DoMaterialSet(triOb, id);
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
      }
   else
      return;     // Do nothing if it can't convert to triObject
   }
예제 #2
0
void NormalMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
   {
   Interval valid = FOREVER;
   int flip, unify;
   pblock->GetValue(PB_FLIP,t,flip,valid);   
   pblock->GetValue(PB_UNIFY,t,unify,valid); 

   // For version 4 and later, we process patch meshes as they are and pass them on.  Earlier
   // versions converted to TriMeshes (done below).  For adding other new types of objects, add
   // them here!
#ifndef NO_PATCHES
   if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
      PatchObject *patchOb = (PatchObject *)os->obj;
      PatchMesh &pmesh = patchOb->GetPatchMesh(t);
      BOOL useSel = pmesh.selLevel >= PO_PATCH;

      if (unify)
         pmesh.UnifyNormals(useSel);

      if (flip)
         pmesh.FlipPatchNormal(useSel ? -1 : -2);
                  
      patchOb->UpdateValidity(TOPO_CHAN_NUM,valid);      
      }
   else  // If it's a TriObject, process it
#endif // NO_PATCHES
   if(os->obj->IsSubClassOf(triObjectClassID)) {
      TriObject *triOb = (TriObject *)os->obj;
      DoNormalSet(triOb, unify, flip);
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
      }

   // Process PolyObjects
   // note: Since PolyObjects must always have the normals alligned they do not 
   // need to support unify and they do not allow normal flips on selected faces
   else if(os->obj->IsSubClassOf(polyObjectClassID)) {
      PolyObject *pPolyOb = (PolyObject *)os->obj;
      MNMesh& mesh = pPolyOb->GetMesh();


      if (flip) {
         // flip selected faces only if entire elements are selected
         if (mesh.selLevel == MNM_SL_FACE) {
            // sca 12/8/2000: Use MNMesh flipping code instead of the code that was here.
            mesh.FlipElementNormals (MN_SEL);
         } else {
            // Flip the entire object if selected elements were not flipped
            for (int i=0; i<mesh.FNum(); i++) {
               mesh.f[i].SetFlag (MN_WHATEVER, !mesh.f[i].GetFlag(MN_DEAD));
            }
            mesh.FlipElementNormals (MN_WHATEVER);
         }

         // Luna task 747:
         // We cannot support specified normals here at this time.
		 // NOTE this assumes that both the topo and geo channels are to be freed
		 // this means that the modifier needs to also set the channels changed to
		 // geo and topo otherwise we will be deleting a channel we dont own.
         mesh.ClearSpecifiedNormals ();
      }

	  pPolyOb->UpdateValidity(GEOM_CHAN_NUM,valid);      
      pPolyOb->UpdateValidity(TOPO_CHAN_NUM,valid);      
      }

   else  // Fallback position: If it can convert to a TriObject, do it!
   if(os->obj->CanConvertToType(triObjectClassID)) {
      TriObject  *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);
      // Now stuff this into the pipeline!
      os->obj = triOb;

      DoNormalSet(triOb, unify, flip);
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
      
      }
   else
      return;     // Do nothing if it can't convert to triObject
   }
예제 #3
0
void SmoothMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) {
   Interval valid = FOREVER;
   int autoSmooth, bits = 0, prevent = 0;
   float thresh = 0.0f;
   pblock->GetValue(sm_autosmooth, t, autoSmooth, valid);
   if (autoSmooth) {
      pblock->GetValue(sm_threshold, t, thresh, valid);
      pblock->GetValue(sm_prevent_indirect, t, prevent, valid);
   } else {
      pblock->GetValue(sm_smoothbits, t, bits, valid);
   }
   // For version 4 and later, we process patch meshes as they are and pass them on.  Earlier
   // versions converted to TriMeshes (done below).  For adding other new types of objects, add
   // them here!
   bool done = false;
#ifndef NO_PATCHES
   if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
      PatchObject *patchOb = (PatchObject *)os->obj;
      PatchMesh &pmesh = patchOb->GetPatchMesh(t);
      BOOL useSel = pmesh.selLevel >= PO_PATCH;

      if (autoSmooth) pmesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int i=0; i<pmesh.getNumPatches(); i++) {
            if (!useSel || pmesh.patchSel[i]) pmesh.patches[i].smGroup = (DWORD)bits;
         }
      }
      pmesh.InvalidateGeomCache();  // Do this because there isn't a topo cache in PatchMesh
      patchOb->UpdateValidity(TOPO_CHAN_NUM,valid);
      done = true;
   }
#endif // NO_PATCHES
   if (!done && os->obj->IsSubClassOf (polyObjectClassID)) {
      PolyObject *pPolyOb = (PolyObject *)os->obj;
      MNMesh &mesh = pPolyOb->GetMesh();

      BOOL useSel = (mesh.selLevel == MNM_SL_FACE);
      if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int faceIndex=0; faceIndex<mesh.FNum(); faceIndex++) {
            if (!useSel || mesh.F(faceIndex)->GetFlag(MN_SEL)) {
               mesh.F(faceIndex)->smGroup = (DWORD)bits;
            }
         }
      }

      // Luna task 747
      // We need to rebuild the smoothing-group-based normals in the normalspec, if any:
      if (mesh.GetSpecifiedNormals()) {
         mesh.GetSpecifiedNormals()->SetParent (&mesh);
         mesh.GetSpecifiedNormals()->BuildNormals ();
         mesh.GetSpecifiedNormals()->ComputeNormals ();
      }

      pPolyOb->UpdateValidity(TOPO_CHAN_NUM,valid);
      done = true;
   }

   TriObject *triOb = NULL;
   if (!done) {
      if (os->obj->IsSubClassOf(triObjectClassID)) triOb = (TriObject *)os->obj;
      else {
         // Convert to triobject if we can.
         if(os->obj->CanConvertToType(triObjectClassID)) {
            TriObject  *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);

            // We'll need to stuff this back into the pipeline:
            os->obj = triOb;

            // Convert validities:
            Interval objValid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
            triOb->SetChannelValidity (TOPO_CHAN_NUM, objValid);
            triOb->SetChannelValidity (GEOM_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, GEOM_CHAN_NUM));
            triOb->SetChannelValidity (TEXMAP_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM));
            triOb->SetChannelValidity (VERT_COLOR_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM));
            triOb->SetChannelValidity (DISP_ATTRIB_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, DISP_ATTRIB_CHAN_NUM));
         }
      }
   }

   if (triOb) {   // one way or another, there's a triobject to smooth.
      Mesh & mesh = triOb->GetMesh();
      BOOL useSel = mesh.selLevel == MESH_FACE;
      if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int i=0; i<mesh.getNumFaces(); i++) {
            if (!useSel || mesh.faceSel[i]) mesh.faces[i].smGroup = (DWORD)bits;
         }
      }
      triOb->GetMesh().InvalidateTopologyCache();
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
   }
}