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 }
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 }
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); } }