void AFRMod::ModifyObject (TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval iv = FOREVER; float f, p, b; int backface; Point3 pt1, pt2; pblock->GetValue(PB_FALLOFF,t,f,iv); pblock->GetValue(PB_PINCH,t,p,iv); pblock->GetValue(PB_BUBBLE,t,b,iv); pblock->GetValue(PB_BACKFACE,t,backface,iv); p1->GetValue(t,&pt1,iv,CTRL_ABSOLUTE); p2->GetValue(t,&pt2,iv,CTRL_ABSOLUTE); if (f==0.0) { os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); return; } Tab<Point3> normals; if (backface) { // Need to get vertex normals. if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; AverageVertexNormals (tobj->GetMesh(), normals); } else if (os->obj->IsSubClassOf (polyObjectClassID)) { PolyObject *pobj = (PolyObject *) os->obj; MNMesh &mesh = pobj->GetMesh(); normals.SetCount (mesh.numv); Point3 *vn = normals.Addr(0); for (int i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) vn[i]=Point3(0,0,0); else vn[i] = mesh.GetVertexNormal (i); } #ifndef NO_PATCHES } else if (os->obj->IsSubClassOf (patchObjectClassID)) { PatchObject *pobj = (PatchObject *) os->obj; normals.SetCount (pobj->NumPoints ()); Point3 *vn = normals.Addr(0); for (int i=0; i<pobj->NumPoints(); i++) vn[i] = pobj->VertexNormal (i); #endif } } if (normals.Count()) { AFRDeformer deformer(mc,f,p,b,pt1,pt2,&normals); os->obj->Deform(&deformer, TRUE); } else { AFRDeformer deformer(mc,f,p,b,pt1,pt2); os->obj->Deform(&deformer, TRUE); } os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); }
void PatchDeformPW::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *incnode) { Interval iv = FOREVER; //TODO: Add the code for actually modifying the object //check is local data if not create it if (mc.localData == NULL) { LocalPatchData *localData = new LocalPatchData(); mc.localData = localData; } LocalPatchData *localData = (LocalPatchData *)mc.localData; if (localData == NULL ) return; if (localData->selfNode == NULL) { localData->selfNode = GetNodeFromModContext(localData); } //check if patch count has changed if so update our uv space //if rebuild then INode *node = NULL; pblock->GetValue(pb_patch,t,node,iv); if (node == NULL) { os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); return; } ObjectState patchos = node->EvalWorldState(t); if ((patchos.obj) && (localData->selfNode)) { iv &= patchos.obj->ObjectValidity(t); Matrix3 patchTM = node->GetObjTMBeforeWSM(t, &iv); Matrix3 baseTM = localData->selfNode->GetObjTMBeforeWSM(t, &iv); PatchObject *patchObj = (PatchObject *) patchos.obj; PatchMesh *patch = &patchObj->patch; BOOL patchValid = TRUE; for (int i =0; i < patch->numPatches; i++) { if (patch->patches[i].type != PATCH_QUAD) { patchValid = FALSE; } } if ((!patchValid) && (ip)) { TSTR name; name.printf(GetString(IDS_ERROR_TRIPATCH)); SetWindowText(GetDlgItem(hWnd,IDC_STATUS),name); } if ((patch->numPatches > 0) && patchValid) { if ( (patch->numPatches != localData->numPatches) || (localData->resample)) { //rebuild the param data BuildParamData(os->obj,localData,patch,patchTM,baseTM); } localData->resample= FALSE; //setup deformer PatchDeformer deformer(localData,patch,baseTM,patchTM); os->obj->Deform(&deformer, TRUE); } } os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); }
void MirrorMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Matrix3 itm = CompMatrix(t,NULL,&mc); Matrix3 tm = Inverse(itm); Interval iv = FOREVER; int axis, copy; float offset; pblock->GetValue(PB_AXIS,t,axis,iv); pblock->GetValue(PB_COPY,t,copy,iv); pblock->GetValue(PB_OFFSET,t,offset,iv); DWORD oldLevel; BOOL convertedShape = FALSE; BitArray oldFaceSelections; // support for TriObjects if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; Mesh &mesh = tobj->GetMesh(); switch (mesh.selLevel) { case MESH_OBJECT: mesh.faceSel.SetAll(); break; case MESH_VERTEX: { for (int i=0; i<mesh.getNumFaces(); i++) { for (int j=0; j<3; j++) { if (mesh.vertSel[mesh.faces[i].v[j]]) { mesh.faceSel.Set(i); } } } break; } case MESH_EDGE: { for (int i=0; i<mesh.getNumFaces(); i++) { for (int j=0; j<3; j++) { if (mesh.edgeSel[i*3+j]) { mesh.faceSel.Set(i); } } } break; } } oldLevel = mesh.selLevel; mesh.selLevel = MESH_FACE; if (copy) { mesh.CloneFaces(mesh.faceSel); mesh.ClearVSelectionWeights (); } if (axis<3) { for (int i=0; i<mesh.getNumFaces(); i++) { if (mesh.faceSel[i]) mesh.FlipNormal(i); } } } #ifndef NO_PATCHES // support for PatchObjects if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *pobj = (PatchObject*)os->obj; PatchMesh &pmesh = pobj->GetPatchMesh(t); switch (pmesh.selLevel) { case PATCH_OBJECT: pmesh.patchSel.SetAll(); break; case PATCH_VERTEX: { for (int i=0; i<pmesh.getNumPatches(); i++) { Patch &p = pmesh.patches[i]; for (int j=0; j<p.type; j++) { if (pmesh.vertSel[p.v[j]]) { pmesh.patchSel.Set(i); break; } } } break; } case PATCH_EDGE: { for (int i=0; i<pmesh.getNumPatches(); i++) { Patch &p = pmesh.patches[i]; for (int j=0; j<p.type; j++) { if (pmesh.edgeSel[p.edge[j]]) { pmesh.patchSel.Set(i); break; } } } break; } } oldLevel = pmesh.selLevel; pmesh.selLevel = PATCH_PATCH; if (copy) pmesh.ClonePatchParts(); // Copy the selected patches if (axis<3) pmesh.FlipPatchNormal(-1); // Flip selected normals } #endif // NO_PATCHES // support for PolyObjects else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject * pPolyOb = (PolyObject*)os->obj; MNMesh &mesh = pPolyOb->GetMesh(); // Luna task 747 // We don't support specified normals here because it would take special code mesh.ClearSpecifiedNormals (); BitArray faceSelections; mesh.getFaceSel (faceSelections); switch (mesh.selLevel) { case MNM_SL_OBJECT: faceSelections.SetAll(); break; case MNM_SL_VERTEX: { faceSelections.ClearAll (); for (int i=0; i<mesh.FNum(); i++) { for (int j=0; j<mesh.F(i)->deg; j++) { int vertIndex = mesh.F(i)->vtx[j]; if (mesh.V(vertIndex)->GetFlag(MN_SEL)) { faceSelections.Set(i); break; } } } break; } case MNM_SL_EDGE: { faceSelections.ClearAll (); for (int i=0; i<mesh.FNum(); i++) { for (int j=0; j<mesh.F(i)->deg; j++) { int edgeIndex = mesh.F(i)->edg[j]; if (mesh.E(edgeIndex)->GetFlag(MN_SEL)) { faceSelections.Set(i); break; } } } break; } } // preserve the existing selection settings oldLevel = mesh.selLevel; mesh.getFaceSel (oldFaceSelections); // set the face selections mesh.ClearFFlags (MN_SEL); mesh.FaceSelect(faceSelections); mesh.selLevel = MNM_SL_FACE; // copy the selected faces and flip Normal direction as needed if (copy) { mesh.CloneFaces(); mesh.freeVSelectionWeights (); } // Now, note that by PolyMesh rules, we can only flip entire selected elements. // So we broaden our selection to include entire elements that are only partially selected: for (int i=0; i<mesh.numf; i++) { if (mesh.f[i].GetFlag (MN_DEAD)) continue; if (!mesh.f[i].GetFlag (MN_SEL)) continue; mesh.PaintFaceFlag (i, MN_SEL); } if (axis<3) { for (i=0; i<mesh.FNum(); i++) { if (mesh.F(i)->GetFlag(MN_SEL)) mesh.FlipNormal(i); } if (mesh.GetFlag (MN_MESH_FILLED_IN)) { // We also need to flip edge normals: for (i=0; i<mesh.ENum(); i++) { if (mesh.f[mesh.e[i].f1].GetFlag (MN_SEL)) { int hold = mesh.e[i].v1; mesh.e[i].v1 = mesh.e[i].v2; mesh.e[i].v2 = hold; } } } } } // support for shape objects else if (os->obj->IsSubClassOf(splineShapeClassID)) { SplineShape *ss = (SplineShape*)os->obj; BezierShape &shape = ss->shape; oldLevel = shape.selLevel; switch (shape.selLevel) { case SHAPE_OBJECT: case SHAPE_VERTEX: shape.selLevel = SHAPE_SPLINE; shape.polySel.SetAll(); break; case SHAPE_SPLINE: case SHAPE_SEGMENT: break; } if (copy) shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE); } else if(os->obj->SuperClassID() == SHAPE_CLASS_ID) { ShapeObject *so = (ShapeObject *)os->obj; if(so->CanMakeBezier()) { SplineShape *ss = new SplineShape(); so->MakeBezier(t, ss->shape); ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t)); os->obj = ss; os->obj->UnlockObject(); convertedShape = TRUE; BezierShape &shape = ss->shape; oldLevel = shape.selLevel; switch (shape.selLevel) { case SHAPE_OBJECT: case SHAPE_VERTEX: shape.selLevel = SHAPE_SPLINE; shape.polySel.SetAll(); break; case SHAPE_SPLINE: case SHAPE_SEGMENT: break; } if (copy) shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE); } } MirrorDeformer deformer(axis,offset,tm,itm); os->obj->Deform(&deformer, TRUE); // if (axis < 3 && splineMethod == SPLINE_REVERSE) { if (os->obj->IsSubClassOf(splineShapeClassID)) { SplineShape *ss = (SplineShape*)os->obj; BezierShape &shape = ss->shape; for (int i = 0; i < shape.bindList.Count(); i++) { int index = 0; int spindex = shape.bindList[i].pointSplineIndex; // Point3 p=shape.splines[spindex]->GetKnot(index).Knot(); if (shape.bindList[i].isEnd) index = shape.splines[spindex]->KnotCount()-1; shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index); shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index); } shape.UpdateBindList(TRUE); } else if(os->obj->SuperClassID() == SHAPE_CLASS_ID) { ShapeObject *so = (ShapeObject *)os->obj; if(so->CanMakeBezier()) { SplineShape *ss = new SplineShape(); so->MakeBezier(t, ss->shape); ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t)); os->obj = ss; os->obj->UnlockObject(); convertedShape = TRUE; BezierShape &shape = ss->shape; for (int i = 0; i < shape.bindList.Count(); i++) { int index = 0; int spindex = shape.bindList[i].pointSplineIndex; // Point3 p; if (shape.bindList[i].isEnd) index = shape.splines[spindex]->KnotCount()-1; shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index); shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index); } shape.UpdateBindList(TRUE); } } } os->obj->UpdateValidity(GEOM_CHAN_NUM,GetValidity(t)); // restore the original selections if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; tobj->GetMesh().selLevel = oldLevel; } #ifndef NO_PATCHES else if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *pobj = (PatchObject*)os->obj; pobj->GetPatchMesh(t).selLevel = oldLevel; } #endif // NO_PATCHES else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *pPolyOb = (PolyObject*)os->obj; pPolyOb->GetMesh().selLevel = oldLevel; pPolyOb->GetMesh().dispFlags = 0; switch (oldLevel) { case MNM_SL_VERTEX: pPolyOb->GetMesh().dispFlags = MNDISP_SELVERTS | MNDISP_VERTTICKS; break; case MNM_SL_EDGE: pPolyOb->GetMesh().dispFlags = MNDISP_SELEDGES; break; case MNM_SL_FACE: pPolyOb->GetMesh().dispFlags = MNDISP_SELFACES; break; } pPolyOb->GetMesh().FaceSelect(oldFaceSelections); } else if(os->obj->IsSubClassOf(splineShapeClassID) || convertedShape) { SplineShape *ss = (SplineShape*)os->obj; ss->shape.selLevel = oldLevel; } }