void SymmetryMod::SlicePolyObject (MNMesh & mesh, Point3 & N, float offset) { // Steve Anderson 9/14/2002 // Using the new "MN_MESH_TEMP_1" flag to override Slice selection behavior, // which is undesirable here. mesh.SetFlag (MN_MESH_TEMP_1); // Slice off everything below the plane: mesh.Slice (N, offset, MNEPS, false, true); mesh.ClearFlag (MN_MESH_TEMP_1); // Make sure we have a valid edge list: if (!mesh.GetFlag (MN_MESH_FILLED_IN)) mesh.FillInMesh(); // Mark the vertices on the plane boundary: mesh.ClearVFlags (MN_USER); for (int i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) continue; float dist = DotProd (N, mesh.P(i)) - offset; if (fabsf(dist) > MNEPS) continue; mesh.v[i].SetFlag (MN_USER); } // Strip out faces on the mirror plane: (These aren't always removed by slice.) // Find the faces that use only mirror-plane vertices: mesh.ClearFFlags (MN_USER); mesh.PropegateComponentFlags (MNM_SL_FACE, MN_USER, MNM_SL_VERTEX, MN_USER, true); mesh.DeleteFlaggedFaces (MN_USER); // Clear out dead components: mesh.CollapseDeadStructs (); }
void VWeldMod::SetPolyFlags (MNMesh & mesh, DWORD flag) { // Convert existing selection (at whatever level) to vertex selection: mesh.ClearVFlags (flag); if (mesh.selLevel == MNM_SL_OBJECT) { for (int i=0; i<mesh.numv; i++) mesh.v[i].SetFlag (flag); } else { mesh.PropegateComponentFlags (MNM_SL_VERTEX, flag, mesh.selLevel, MN_SEL); } }
void SymmetryMod::WeldPolyObject (MNMesh & mesh, Point3 & N, float offset, float threshold) { // Mark the vertices within the welding threshold of the plane: mesh.ClearVFlags (MN_USER); for (int i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) continue; float dist = DotProd (N, mesh.P(i)) - offset; if (fabsf(dist) > threshold) continue; mesh.v[i].SetFlag (MN_USER); } // Do the welding: if (mesh.WeldBorderVerts (threshold, MN_USER)) { // If result was true, we have some MN_DEAD components: mesh.CollapseDeadStructs (); } }
void SelectByChannel::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { //TODO: Add the code for actually modifying the object //get th map id // TriObject *tobj = (TriObject*)os->obj; // Mesh &mesh = tobj->GetMesh(); Mesh *mesh = NULL; MNMesh *mnmesh = NULL; TriObject *collapsedtobj = NULL; if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; mesh = &tobj->GetMesh(); } else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *pobj = (PolyObject*)os->obj; mnmesh = &pobj->GetMesh(); } int mapID; int subID; int selType; pblock->GetValue(pb_mapid,0,mapID,FOREVER); pblock->GetValue(pb_mapsubid,0,subID,FOREVER); pblock->GetValue(pb_seltype,0,selType,FOREVER); if (subID < 0) subID = 0; if (subID > 2) subID = 2; if (mnmesh) { int numMaps = mnmesh->numm; mnmesh->dispFlags = MNDISP_VERTTICKS|MNDISP_SELVERTS ; mnmesh->selLevel = MNM_SL_VERTEX; if (mapID < numMaps) { UVVert *uvw = mnmesh->M(mapID)->v; MNMapFace *uvwFace = mnmesh->M(mapID)->f; if (uvw && uvwFace) { float *vsw = NULL; MNFace *face = mnmesh->f; vsw = mnmesh->getVSelectionWeights (); if (vsw == NULL) { mnmesh->SupportVSelectionWeights(); vsw = mnmesh->getVSelectionWeights (); } BitArray processed; processed.SetSize(mnmesh->numv); processed.ClearAll(); if (vsw && uvwFace && uvw) { if (selType == 0) { mnmesh->ClearVFlags (MN_SEL); for (int i = 0; i < mnmesh->numv; i++) vsw[i] = 0.0f; } for (int i = 0; i < mnmesh->numf; i++) { int deg = face[i].deg; for (int j = 0; j < deg; j++) { int index = uvwFace[i].tv[j]; int gindex = face[i].vtx[j]; if (!processed[gindex]) { processed.Set(gindex); if (selType == 0) { float w = uvw[index][subID]; if (w >= 1.0f) mnmesh->v[gindex].SetFlag (MN_SEL); // mesh.vertSel.Set(gindex); else vsw[gindex] = uvw[index][subID]; } else if (selType == 1) { float w = uvw[index][subID]; w += vsw[gindex]; if (w >= 1.0f) mnmesh->v[gindex].SetFlag (MN_SEL); // mesh.vertSel.Set(gindex); else vsw[gindex] = uvw[index][subID]; } else if (selType == 2) { float w = uvw[index][subID]; if (mnmesh->v[gindex].GetFlag (MN_SEL))//(mesh.vertSel[gindex]) w = 1.0f - w; else w = vsw[gindex] - w;; if (w < 1.0f) mnmesh->v[gindex].ClearFlag (MN_SEL); // mesh.vertSel.Set(gindex,FALSE); vsw[gindex] = w; } } } } } } } } else if (mesh) { mesh->dispFlags = DISP_VERTTICKS|DISP_SELVERTS; mesh->selLevel = MESH_VERTEX; if (mesh->mapSupport(mapID)) { UVVert *uvw = mesh->mapVerts(mapID); TVFace *uvwFace = mesh->mapFaces(mapID); float *vsw = NULL; Face *face = mesh->faces; vsw = mesh->getVSelectionWeights (); if (vsw == NULL) { mesh->SupportVSelectionWeights(); vsw = mesh->getVSelectionWeights (); } BitArray processed; processed.SetSize(mesh->numVerts); processed.ClearAll(); if (vsw && uvwFace && uvw) { if (selType == 0) { mesh->vertSel.ClearAll(); for (int i = 0; i < mesh->numVerts; i++) vsw[i] = 0.0f; } for (int i = 0; i < mesh->numFaces; i++) { for (int j = 0; j < 3; j++) { int index = uvwFace[i].t[j]; int gindex = face[i].v[j]; if (!processed[gindex]) { processed.Set(gindex); if (selType == 0) { float w = uvw[index][subID]; if (w >= 1.0f) mesh->vertSel.Set(gindex); else vsw[gindex] = uvw[index][subID]; } else if (selType == 1) { float w = uvw[index][subID]; w += vsw[gindex]; if (w >= 1.0f) mesh->vertSel.Set(gindex); else vsw[gindex] = uvw[index][subID]; } else if (selType == 2) { float w = uvw[index][subID]; if (mesh->vertSel[gindex]) w = 1.0f - w; else w = vsw[gindex] - w;; if (w < 1.0f) mesh->vertSel.Set(gindex,FALSE); vsw[gindex] = w; } } } } } } } Interval iv; iv = FOREVER; os->obj->PointsWereChanged(); iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM); iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM); iv = iv & os->obj->ChannelValidity(t,SELECT_CHAN_NUM); os->obj->UpdateValidity (SELECT_CHAN_NUM, iv); }
void MapChannelPaste::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { //TODO: Add the code for actually modifying the object //get th map id int mapID; pblock->GetValue(pb_mapid,0,mapID,FOREVER); mapID = buffer.pasteToChannel; BOOL useMap; pblock->GetValue(pb_usemap,0,useMap,FOREVER); //get the mesh Mesh *mesh = NULL; MNMesh *mnmesh = NULL; PatchMesh *pmesh = NULL; TriObject *collapsedtobj = NULL; if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; mesh = &tobj->GetMesh(); } else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *pobj = (PolyObject*)os->obj; mnmesh = &pobj->GetMesh(); } #ifndef NO_PATCHES else if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *pobj = (PatchObject*)os->obj; pmesh = &pobj->patch; } #endif // NO_PATCHES // TriObject *tobj = (TriObject*)os->obj; // Mesh &mesh = tobj->GetMesh(); if (pmesh) { if ( (buffer.numRealFaces == pmesh->numPatches) && (buffer.patchDeg.Count() == pmesh->numPatches) && ((buffer.pasteToChannelType == PATCHMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP))) { BOOL gvalid = TRUE; for (int i = 0; i < pmesh->numPatches; i++) { int sDeg, tDeg; sDeg = buffer.patchDeg[i]; tDeg = 3; if (pmesh->patches[i].type == PATCH_QUAD) tDeg = 4; if (tDeg != sDeg) gvalid = FALSE; } if (gvalid) { if ((buffer.pasteToChannelType == PATCHMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP)) { int numMaps = pmesh->getNumMaps(); BOOL clear = FALSE; if (!pmesh->getMapSupport(mapID)) { pmesh->setMapSupport(mapID, TRUE); clear = TRUE; } //if last channel reduce the number of channels if (buffer.pasteToSubID == -50) pmesh->setNumMapVerts(mapID, buffer.verts.Count()); else pmesh->setNumMapVerts(mapID, buffer.w.Count()); PatchTVert *uvw = pmesh->mapVerts(mapID); TVPatch *uvwFace = pmesh->tvPatches[mapID];//mesh->mapFaces(mapID); int ct = buffer.verts.Count(); if (buffer.pasteToSubID != -50) ct = buffer.w.Count(); for (int i = 0; i < ct; i++) { if (buffer.pasteToSubID == -50) uvw[i] = buffer.verts[i]; else { if (clear) uvw[i].p = Point3(0.0f,0.0f,0.0f); uvw[i].p[buffer.pasteToSubID] = buffer.w[i]; } } for (int i = 0; i < buffer.numFaces; i++) { uvwFace[i] = buffer.uvwPatchFaces[i]; } } } } } else if (mnmesh) { if (buffer.numRealFaces == mnmesh->numf) { BOOL gvalid = TRUE; for (int i = 0; i < mnmesh->numf; i++) { int sDeg, tDeg; if (buffer.copyType == POLYMAPCHANNEL) sDeg = buffer.uvwMNFaces[i]->deg; else sDeg = buffer.geomMNFaces[i]->deg; tDeg = mnmesh->f[i].deg; if (tDeg != sDeg) gvalid = FALSE; } if (gvalid) { if ((buffer.pasteToChannelType == POLYMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP)) { int numMaps = mnmesh->numm; BOOL clear = FALSE; if (mapID >= numMaps) { mnmesh->SetMapNum(mapID+1); mnmesh->InitMap(mapID); clear = TRUE; } // MNMap *map = mnmesh->M(mapID); MNMapFace *uvwFace = mnmesh->M(mapID)->f; if (!uvwFace) { mnmesh->InitMap(mapID); uvwFace = mnmesh->M(mapID)->f; clear = TRUE; } //if last channel reduce the number of channels if (buffer.pasteToSubID == -50) { if (buffer.copyType == POLYMESH_GEOM) mnmesh->M(mapID)->setNumVerts(buffer.mnVerts.Count()); else mnmesh->M(mapID)->setNumVerts(buffer.verts.Count()); } else mnmesh->M(mapID)->setNumVerts(buffer.w.Count()); Point3 *uvw = mnmesh->M(mapID)->v; int ct = mnmesh->M(mapID)->numv;//buffer.mnVerts.Count(); if (buffer.pasteToSubID != -50) ct = buffer.w.Count(); for (int i = 0; i < ct; i++) { if (buffer.pasteToSubID == -50) { if (buffer.copyType == POLYMESH_GEOM) uvw[i] = buffer.mnVerts[i].p; else uvw[i] = buffer.verts[i]; } else { if (clear) uvw[i] = Point3(0.0f,0.0f,0.0f); uvw[i][buffer.pasteToSubID] = buffer.w[i]; } } if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { int deg = buffer.geomMNFaces[i]->deg; uvwFace[i].MakePoly(deg,buffer.geomMNFaces[i]->vtx); } } else { for (int i = 0; i < buffer.numFaces; i++) { uvwFace[i] = *buffer.uvwMNFaces[i]; } } } else if ((buffer.pasteToChannelType == POLYGEOMCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_GEOM)) { int ct = buffer.mnVerts.Count(); if (buffer.copyType == POLYMESH_MAP) ct = buffer.verts.Count(); if (buffer.pasteToSubID != -50) ct = buffer.w.Count(); if (buffer.pasteToSubID == -50) { if (buffer.copyType == POLYMESH_GEOM) mnmesh->setNumVerts(buffer.mnVerts.Count()); else mnmesh->setNumVerts(buffer.verts.Count()); } else mnmesh->setNumVerts(buffer.w.Count()); MNVert *verts = mnmesh->v; MNFace *geomFace = mnmesh->f; for (int i = 0; i < ct; i++) { if (buffer.pasteToSubID == -50) { if (buffer.copyType == POLYMESH_GEOM) verts[i] = buffer.mnVerts[i]; else verts[i].p = buffer.verts[i]; } else verts[i].p[buffer.pasteToSubID] = buffer.w[i]; } if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { geomFace[i] = *buffer.geomMNFaces[i]; } } else { for (int i = 0; i < buffer.numFaces; i++) { geomFace[i].MakePoly(buffer.uvwMNFaces[i]->deg,buffer.uvwMNFaces[i]->tv); // geomFace[i].v[0] = buffer.uvwMNFaces[i].t[0]; // geomFace[i].v[1] = buffer.uvwMNFaces[i].t[1]; // geomFace[i].v[2] = buffer.uvwMNFaces[i].t[2]; } } } else if ((buffer.pasteToChannelType == POLYSELCHANNEL) || (buffer.pasteToChannelType == CHANNEL_SEL)) { MNVert *verts = mnmesh->v; MNFace *geomFace = mnmesh->f; mnmesh->SupportVSelectionWeights(); float *vsw = NULL; vsw = mnmesh->getVSelectionWeights (); mnmesh->ClearVFlags (MN_SEL); // mesh->vertSel.ClearAll(); /* for (int i = 0; i < buffer.w.Count(); i++) { if (vsw) { vsw[i] = buffer.w[i]; if (vsw[i] >= 1.0f) mnmesh->v[i].SetFlag (MN_SEL); } } */ if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { // geomFace[i] = *buffer.geomMNFaces[i]; for (int k = 0; k < geomFace[i].deg; k++) { // geomFace[i].vtx[k] = buffer.uvwMNFaces[i]->tv[k]; int id = buffer.geomMNFaces[i]->vtx[k]; int gid = geomFace[i].vtx[k]; if (vsw) { vsw[gid] = buffer.w[id]; } } } } else { for (int i = 0; i < buffer.numFaces; i++) { for (int k = 0; k < geomFace[i].deg; k++) { // geomFace[i].vtx[k] = buffer.uvwMNFaces[i]->tv[k]; int id = buffer.uvwMNFaces[i]->tv[k]; int gid = geomFace[i].vtx[k]; if (vsw) { vsw[gid] = buffer.w[id]; } } } } for (int i = 0; i < mnmesh->numv; i++) { if (vsw) { if (vsw[i] >= 1.0f) mnmesh->v[i].SetFlag (MN_SEL); } } mnmesh->dispFlags =MNDISP_VERTTICKS |MNDISP_SELVERTS ; mnmesh->selLevel = MNM_SL_VERTEX ; } } } } else if (mesh) { if (buffer.numFaces == mesh->numFaces) { if ((buffer.pasteToChannelType == TRIMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP)) { int numMaps = mesh->getNumMaps(); BOOL clear = FALSE; if (!mesh->mapSupport(mapID)) { mesh->setMapSupport(mapID, TRUE); clear = TRUE; } //if last channel reduce the number of channels if (buffer.pasteToSubID == -50) mesh->setNumMapVerts(mapID, buffer.verts.Count()); else mesh->setNumMapVerts(mapID, buffer.w.Count()); UVVert *uvw = mesh->mapVerts(mapID); TVFace *uvwFace = mesh->mapFaces(mapID); int ct = buffer.verts.Count(); if (buffer.pasteToSubID != -50) ct = buffer.w.Count(); for (int i = 0; i < ct; i++) { if (buffer.pasteToSubID == -50) uvw[i] = buffer.verts[i]; else { if (clear) uvw[i] = Point3(0.0f,0.0f,0.0f); uvw[i][buffer.pasteToSubID] = buffer.w[i]; } } if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { uvwFace[i].t[0] = buffer.geomFaces[i].v[0]; uvwFace[i].t[1] = buffer.geomFaces[i].v[1]; uvwFace[i].t[2] = buffer.geomFaces[i].v[2]; } } else { for (int i = 0; i < buffer.numFaces; i++) { uvwFace[i] = buffer.uvwFaces[i]; } } } else if ((buffer.pasteToChannelType == TRIGEOMCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_GEOM)) { int ct = buffer.verts.Count(); if (buffer.pasteToSubID != -50) ct = buffer.w.Count(); if (buffer.pasteToSubID == -50) mesh->setNumVerts(buffer.verts.Count()); else mesh->setNumVerts(buffer.w.Count()); Point3 *verts = mesh->verts; Face *geomFace = mesh->faces; for (int i = 0; i < ct; i++) { if (buffer.pasteToSubID == -50) verts[i] = buffer.verts[i]; else verts[i][buffer.pasteToSubID] = buffer.w[i]; } if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { geomFace[i] = buffer.geomFaces[i]; } } else { for (int i = 0; i < buffer.numFaces; i++) { geomFace[i].v[0] = buffer.uvwFaces[i].t[0]; geomFace[i].v[1] = buffer.uvwFaces[i].t[1]; geomFace[i].v[2] = buffer.uvwFaces[i].t[2]; } } } else if ((buffer.pasteToChannelType == TRISELCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_SEL)) { Point3 *verts = mesh->verts; Face *geomFace = mesh->faces; mesh->SupportVSelectionWeights(); float *vsw = NULL; vsw = mesh->getVSelectionWeights (); mesh->vertSel.ClearAll(); for (int i = 0; i <mesh->vertSel.GetSize(); i++) { if (vsw) vsw[i] = 0.0f; } /* for (int i = 0; i < buffer.w.Count(); i++) { if (vsw) { vsw[i] = buffer.w[i]; if (vsw[i] >= 1.0f) mesh->vertSel.Set(i); } } */ if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL)) { for (int i = 0; i < buffer.numFaces; i++) { // geomFace[i] = buffer.geomFaces[i]; int id = buffer.geomFaces[i].v[0]; if (vsw) vsw[id] = buffer.w[id]; id = buffer.geomFaces[i].v[1]; if (vsw) vsw[id] = buffer.w[id]; id = buffer.geomFaces[i].v[1]; if (vsw) vsw[id] = buffer.w[id]; } } else { for (int i = 0; i < buffer.numFaces; i++) { // geomFace[i].v[0] = buffer.uvwFaces[i].t[0]; // geomFace[i].v[1] = buffer.uvwFaces[i].t[1]; // geomFace[i].v[2] = buffer.uvwFaces[i].t[2]; int id = buffer.uvwFaces[i].t[0]; int gid = mesh->faces[i].v[0]; if (vsw) vsw[gid] = buffer.w[id]; id = buffer.uvwFaces[i].t[1]; gid = mesh->faces[i].v[1]; if (vsw) vsw[gid] = buffer.w[id]; id = buffer.uvwFaces[i].t[2]; gid = mesh->faces[i].v[2]; if (vsw) vsw[gid] = buffer.w[id]; } } for (int i = 0; i < mesh->numVerts; i++) { if (vsw) { // vsw[i] = buffer.w[i]; if (vsw[i] >= 1.0f) mesh->vertSel.Set(i); } } mesh->dispFlags = DISP_VERTTICKS|DISP_SELVERTS; mesh->selLevel = MESH_VERTEX; } } mesh->InvalidateTopologyCache(); } Interval iv; iv = FOREVER; os->obj->PointsWereChanged(); iv &= os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM); iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM); iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM); iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM); iv = iv & os->obj->ChannelValidity(t,SELECT_CHAN_NUM); os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); os->obj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv); os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv); os->obj->UpdateValidity (SELECT_CHAN_NUM, iv); }