void ConvertToPoly::Convert (PolyObject *obj, TimeValue t, MNMesh & mm, Interval & ivalid) { int keepConvex; int limitSize; int maxdeg=0; int keepPlanar, elimCollin; float planarThresh = 0.0f; pblock->GetValue (turn_keep_convex, t, keepConvex, ivalid); pblock->GetValue (turn_limit_size, t, limitSize, ivalid); if (limitSize) pblock->GetValue (turn_max_size, t, maxdeg, ivalid); pblock->GetValue (turn_planar, t, keepPlanar, ivalid); if (keepPlanar) { pblock->GetValue (turn_thresh, t, planarThresh, ivalid); planarThresh = cosf (planarThresh); } pblock->GetValue (turn_eliminate_collinear, t, elimCollin, ivalid); mm = obj->mm; // Luna task 747 // We cannot support specified normals in Convert to Poly at this time. mm.ClearSpecifiedNormals(); if (!mm.GetFlag (MN_MESH_FILLED_IN)) mm.FillInMesh (); if (!mm.GetFlag (MN_MESH_NO_BAD_VERTS)) mm.EliminateBadVerts (); if (maxdeg) mm.RestrictPolySize (maxdeg); if (keepConvex) mm.MakeConvex (); if (maxdeg || keepConvex) mm.ClearEFlags (MN_EDGE_INVIS); if (keepPlanar) mm.MakePlanar (planarThresh); if (elimCollin) mm.EliminateCollinearVerts (); mm.selLevel = obj->mm.selLevel; }
void EditFaceDataModData::ApplyChanges (MNMesh & mesh) { // Make sure we're sized correctly for this mesh. // (NOTE: If the user reduces, then increases input number of faces, we lose data.) if (mesh.numf != mFaceSel.GetSize()) SynchSize (mesh.numf); // Set the selection: mesh.FaceSelect (mFaceSel); // Get the face data manager from the mesh: DebugPrint ("EditFaceDataMod: Getting manager from MNMesh (0x%08x)\n", &mesh); IFaceDataMgr *pFDMgr = static_cast<IFaceDataMgr*>(mesh.GetInterface (FACEDATAMGR_INTERFACE)); if (pFDMgr == NULL) return; SampleFaceData* fdc = dynamic_cast<SampleFaceData*>(pFDMgr->GetFaceDataChan( FACE_MAXSAMPLEUSE_CLSID )); if ( fdc == NULL ) { // The mesh does not have our sample face-data channel so we will add it here fdc = new SampleFaceData(); fdc->FacesCreated (0, mFaceSel.GetSize()); pFDMgr->AddFaceDataChan( fdc ); } if (!mFacesAffected.NumberSet ()) return; for (int i=0; i<mFacesAffected.GetSize(); i++) { if (!mFacesAffected[i]) continue; fdc->SetValue (i, mtNewFaceValues[i]); } }
void PolyOpExtrudeEdge::Do (MNMesh & mesh) { MNChamferData chamData; chamData.InitToMesh(mesh); Tab<Point3> tUpDir; tUpDir.SetCount (mesh.numv); // Topology change: if (!mesh.ExtrudeEdges (MN_USER, &chamData, tUpDir)) return; // Apply map changes based on base width: int i; Tab<UVVert> tMapDelta; for (int mapChannel=-NUM_HIDDENMAPS; mapChannel<mesh.numm; mapChannel++) { if (mesh.M(mapChannel)->GetFlag (MN_DEAD)) continue; chamData.GetMapDelta (mesh, mapChannel, mWidth, tMapDelta); UVVert *pMapVerts = mesh.M(mapChannel)->v; if (!pMapVerts) continue; for (i=0; i<mesh.M(mapChannel)->numv; i++) pMapVerts[i] += tMapDelta[i]; } // Apply geom changes based on base width: Tab<Point3> tDelta; chamData.GetDelta (mWidth, tDelta); for (i=0; i<mesh.numv; i++) mesh.v[i].p += tDelta[i]; // Move the points up: for (i=0; i<tUpDir.Count(); i++) mesh.v[i].p += tUpDir[i]*mHeight; }
void PolyOpExtrudeFace::Do(MNMesh & mesh) { MNChamferData chamData; if (mType<2) { MNFaceClusters fclust(mesh, MN_USER); if (!mesh.ExtrudeFaceClusters (fclust)) return; if (mType == 0) { // Get fresh face clusters: MNFaceClusters fclustAfter(mesh, MN_USER); Tab<Point3> clusterNormals, clusterCenters; fclustAfter.GetNormalsCenters (mesh, clusterNormals, clusterCenters); mesh.GetExtrudeDirection (&chamData, &fclustAfter, clusterNormals.Addr(0)); } else { mesh.GetExtrudeDirection (&chamData, MN_USER); } } else { // Polygon-by-polygon extrusion. if (!mesh.ExtrudeFaces (MN_USER)) return; MNFaceClusters fclustAfter(mesh, MN_USER); Tab<Point3> clusterNormals, clusterCenters; fclustAfter.GetNormalsCenters (mesh, clusterNormals, clusterCenters); mesh.GetExtrudeDirection (&chamData, &fclustAfter, clusterNormals.Addr(0)); } // Move vertices for (int i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) continue; mesh.v[i].p += chamData.vdir[i]*mHeight; } }
int EditFaceDataMod::HitTest (TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { Interval valid; int savedLimits, res = 0; GraphicsWindow *gw = vpt->getGW(); HitRegion hr; // Setup GW MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); Matrix3 mat = inode->GetObjectTM(t); gw->setTransform(mat); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->clearHitCode(); if (!mc->localData) return 0; EditFaceDataModData *md = (EditFaceDataModData*)mc->localData; Mesh *mesh = md->GetCacheMesh (); MNMesh *mnmesh = md->GetCacheMNMesh (); SubObjHitList hitList; if (mesh) { res = mesh->SubObjectHitTest(gw, gw->getMaterial(), &hr, flags|hitLevel[selLevel], hitList); } else if (mnmesh) { res = mnmesh->SubObjectHitTest (gw, gw->getMaterial(), &hr, flags|mnhitLevel[selLevel], hitList); } MeshSubHitRec *rec = hitList.First(); while (rec) { vpt->LogHit(inode,mc,rec->dist,rec->index,NULL); rec = rec->Next(); } gw->setRndLimits(savedLimits); return res; }
void EditFaceDataMod::GetSubObjectTMs (SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) { if (!mc->localData) return; if (selLevel == SEL_OBJECT) return; // shouldn't happen. EditFaceDataModData *modData = (EditFaceDataModData *) mc->localData; Mesh *mesh = modData->GetCacheMesh(); MNMesh *mnmesh = modData->GetCacheMNMesh(); if (!mesh && !mnmesh) return; Matrix3 tm = node->GetObjectTM(t); Box3 box; if (mesh) { BitArray sel = mesh->VertexTempSel (); if (!sel.NumberSet()) return; for (int i=0; i<mesh->numVerts; i++) if (sel[i]) box += mesh->verts[i] * tm; } else { int numSel, which; float value; bool valueDetermined; modData->DescribeSelection (numSel, which, value, valueDetermined); if (!numSel) return; if (numSel==1) { for (int j=0; j<mnmesh->f[which].deg; j++) box += mnmesh->P(mnmesh->f[which].vtx[j]) * tm; } else { for (int i=0; i<mnmesh->numf; i++) { if (mnmesh->f[i].GetFlag (MN_DEAD)) continue; if (!modData->GetFaceSel()[i]) continue; for (int j=0; j<mnmesh->f[i].deg; j++) box += mnmesh->P(mnmesh->f[i].vtx[j]) * tm; } } } Matrix3 ctm(1); ctm.SetTrans (box.Center()); cb->TM (ctm,0); }
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 get_convex_hull(Mesh& mesh, Mesh& outmesh) { MNMesh mn; map<int, int> ptmap; vector<Vector3> vertmap; for (int i = 0; i < mesh.getNumVerts(); ++i) { Vector3 temp(mesh.getVert(i).x, mesh.getVert(i).y, mesh.getVert(i).z); vertmap.push_back(temp); } vector<Triangle> outshape = NifQHull::compute_convex_hull(vertmap); vector<Triangle>::size_type sz = outshape.size(); for (int i = 0; i < mesh.getNumVerts(); ++i) { mn.NewVert(Point3(mesh.getVert(i).x, mesh.getVert(i).y, mesh.getVert(i).z)); } for (unsigned i = 0; i < sz; i++) { mn.NewTri(outshape[i].v1, outshape[i].v2, outshape[i].v3); } mn.EliminateIsoMapVerts(); mn.MakeConvex(); mn.FillInMesh(); mn.EliminateBadVerts(0); mn.Triangulate(); mn.OutToTri(outmesh); }
void PolyOpChamferEdge::Do (MNMesh & mesh) { MNChamferData *pMeshChamData = new MNChamferData; mesh.ChamferEdges (MN_USER, pMeshChamData); Tab<UVVert> mapDelta; for (int mapChannel = -NUM_HIDDENMAPS; mapChannel<mesh.numm; mapChannel++) { if (mesh.M(mapChannel)->GetFlag (MN_DEAD)) continue; pMeshChamData->GetMapDelta (mesh, mapChannel, mAmount, mapDelta); for (int i=0; i<mapDelta.Count(); i++) mesh.M(mapChannel)->v[i] += mapDelta[i]; } Tab<Point3> vertexDelta; pMeshChamData->GetDelta (mAmount, vertexDelta); for (int i=0; i<vertexDelta.Count(); i++) mesh.P(i) += vertexDelta[i]; }
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 PolyOpWeldVertex::Do(MNMesh & mesh) { // Weld the suitable border vertices: bool haveWelded = false; if (mesh.WeldBorderVerts (mThreshold, MN_USER)) { mesh.CollapseDeadStructs (); haveWelded = true; } // Weld vertices that share short edges: if (WeldShortPolyEdges (mesh, MN_USER)) haveWelded = true; if (haveWelded) { mesh.InvalidateTopoCache (); mesh.FillInMesh (); } }
void ConvertToPoly::Convert (TriObject *obj, TimeValue t, MNMesh & mm, Interval & ivalid) { int keepConvex; int limitSize; int maxdeg=0; int keepPlanar; float planarThresh = 0.0f; int elimCollin; pblock->GetValue (turn_keep_convex, t, keepConvex, ivalid); pblock->GetValue (turn_limit_size, t, limitSize, ivalid); if (limitSize) pblock->GetValue (turn_max_size, t, maxdeg, ivalid); pblock->GetValue (turn_planar, t, keepPlanar, ivalid); if (keepPlanar) { pblock->GetValue (turn_thresh, t, planarThresh, ivalid); planarThresh = cosf (planarThresh); } pblock->GetValue (turn_eliminate_collinear, t, elimCollin, ivalid); mm.AddTri (obj->mesh); mm.FillInMesh (); mm.EliminateBadVerts (); if (maxdeg != 3) { if (keepPlanar) mm.FenceNonPlanarEdges (planarThresh, TRUE); mm.MakePolyMesh (maxdeg, elimCollin); if (keepConvex) mm.MakeConvex (); } mm.ClearEFlags (MN_EDGE_INVIS); switch (obj->mesh.selLevel) { case MESH_VERTEX: mm.selLevel = MNM_SL_VERTEX; break; case MESH_EDGE: mm.selLevel = MNM_SL_EDGE; break; case MESH_FACE: mm.selLevel = MNM_SL_FACE; break; default: mm.selLevel = MNM_SL_OBJECT; break; } }
bool PolyOpWeldVertex::WeldShortPolyEdges (MNMesh & mesh, DWORD vertFlag) { // In order to collapse vertices, we turn them into edge selections, // where the edges are shorter than the weld threshold. bool canWeld = false; mesh.ClearEFlags (MN_USER); float threshSq = mThreshold*mThreshold; for (int i=0; i<mesh.nume; i++) { if (mesh.e[i].GetFlag (MN_DEAD)) continue; if (!mesh.v[mesh.e[i].v1].GetFlag (vertFlag)) continue; if (!mesh.v[mesh.e[i].v2].GetFlag (vertFlag)) continue; if (LengthSquared (mesh.P(mesh.e[i].v1) - mesh.P(mesh.e[i].v2)) > threshSq) continue; mesh.e[i].SetFlag (MN_USER); canWeld = true; } if (!canWeld) return false; return MNMeshCollapseEdges (mesh, MN_USER); }
void PolyOpRetriangulate::Do (MNMesh & mesh) { int i; for (i=0; i<mesh.numf; i++) { if (mesh.f[i].GetFlag (MN_DEAD)) continue; if (!mesh.f[i].GetFlag (MN_USER)) continue; mesh.RetriangulateFace (i); } }
void SMBrushSculpt::Proc(ViewExp *vpt, const SMHit &hit, IPoint2 &m, IPoint2 &lastm) { if (!m_stroking || SMHit_hasNoFaceHit(hit)) return; int startid = SMHit_getSOid(hit,m_subobj); Point3 startpos = hit.face.pos; MNMeshConVertBuffer *mcon = m_SM->GetMConVert(); // compute affected + distances mcon->SeedSingle(m_subobj,startid,m_SM->m_brushsize,startpos,TRUE,m_SM->m_ip->SelectionFrozen()); mcon->BuildAffectedSoft(m_SM->m_brushsize,startpos); mcon->AffectedDistWeights(hit.brushinner,hit.brush); // run sculpt MNMesh* mesh = m_SM->m_mesh; Point3 extrudedir = (m_SM->m_workplane.IsLocal()) ? mcon->GetAffectedNormal(TRUE) : m_SM->m_workplane.GetNormal(); extrudedir *= m_dirsign * hit.pressure * m_speed; IMNMeshUtilities8* mesh8 = static_cast<IMNMeshUtilities8*>(mesh->GetInterface( IMNMESHUTILITIES8_INTERFACE_ID )); MNMeshConVertIter it; MNMeshConVertIter itend; mcon->GetIterators(it,itend); MESHCONVERT_IT_MASK(mcon->GetMasked()) mesh->v[it->vid].p += extrudedir*it->dist; #if MAX_RELEASE >= 9000 mesh8->InvalidateVertexCache(it->vid); #endif MESHCONVERT_IT_NORM mesh->v[it->vid].p += extrudedir*it->dist; #if MAX_RELEASE >= 9000 mesh8->InvalidateVertexCache(it->vid); #endif MESHCONVERT_IT_END; // update draw geo MNMesh_updateDrawGeo(mesh,m_SM->m_polyobj); }
// (This code was copied from EditPolyObj::EpfnCollapse.) bool VWeldMod::WeldShortPolyEdges (MNMesh & mesh, float thresh, DWORD flag) { // In order to collapse vertices, we turn them into edge selections, // where the edges are shorter than the weld threshold. bool canWeld = false; mesh.ClearEFlags (flag); float threshSq = thresh*thresh; for (int i=0; i<mesh.nume; i++) { if (mesh.e[i].GetFlag (MN_DEAD)) continue; if (!mesh.v[mesh.e[i].v1].GetFlag (flag)) continue; if (!mesh.v[mesh.e[i].v2].GetFlag (flag)) continue; if (LengthSquared (mesh.P(mesh.e[i].v1) - mesh.P(mesh.e[i].v2)) > threshSq) continue; mesh.e[i].SetFlag (flag); canWeld = true; } if (!canWeld) return false; MNMeshUtilities mmu(&mesh); return mmu.CollapseEdges (MN_USER); }
void SymmetryMod::MirrorPolyObject (MNMesh & mesh, int axis, Matrix3 & tm, Matrix3 & itm) { // Create scaling matrix for mirroring on selected axis: Point3 scale(1,1,1); scale[axis] = -1.0f; itm.Scale(scale,TRUE); // Make the mirror copy of the entire mesh: int oldnumv = mesh.numv; for (int i=0; i<mesh.numf; i++) mesh.f[i].SetFlag (MN_USER); mesh.CloneFaces (MN_USER, true); // Transform the vertices to their mirror images: for (int i=oldnumv; i<mesh.numv; i++) mesh.v[i].p = (itm*mesh.v[i].p)*tm; // Flip over faces, edges: mesh.FlipElementNormals (MN_USER); // flag should now be set only on clones. DbgAssert (mesh.CheckAllData ()); }
void PolyOpBevelFace::Do (MNMesh & mesh) { // Topological extrusion first: MNChamferData chamData; if (mType<2) { MNFaceClusters fclust(mesh, MN_USER); if (!mesh.ExtrudeFaceClusters (fclust)) return; if (mType == 0) { // Get fresh face clusters: MNFaceClusters fclustAfter(mesh, MN_USER); Tab<Point3> clusterNormals, clusterCenters; fclustAfter.GetNormalsCenters (mesh, clusterNormals, clusterCenters); mesh.GetExtrudeDirection (&chamData, &fclustAfter, clusterNormals.Addr(0)); } else { mesh.GetExtrudeDirection (&chamData, MN_USER); } } else { // Polygon-by-polygon extrusion. if (!mesh.ExtrudeFaces (MN_USER)) return; MNFaceClusters fclustAfter(mesh, MN_USER); Tab<Point3> clusterNormals, clusterCenters; fclustAfter.GetNormalsCenters (mesh, clusterNormals, clusterCenters); mesh.GetExtrudeDirection (&chamData, &fclustAfter, clusterNormals.Addr(0)); } int i; if (mHeight) { for (i=0; i<mesh.numv; i++) mesh.v[i].p += chamData.vdir[i]*mHeight; } if (mOutline) { MNTempData temp(&mesh); Tab<Point3> *outDir; if (mType == 0) outDir = temp.OutlineDir (MESH_EXTRUDE_CLUSTER, MN_USER); else outDir = temp.OutlineDir (MESH_EXTRUDE_LOCAL, MN_USER); if (outDir && outDir->Count()) { Point3 *od = outDir->Addr(0); for (i=0; i<mesh.numv; i++) mesh.v[i].p += od[i]*mOutline; } } }
void ConvertToPoly::Convert (PatchObject *obj, TimeValue t, MNMesh & mm, Interval & ivalid) { int selConv, useSoftSel; int keepConvex, limitSize; int maxdeg=0; int keepPlanar; float planarThresh = 0.0f; int elimCollin; pblock->GetValue (turn_sel_type, t, selConv, ivalid); pblock->GetValue (turn_softsel, t, useSoftSel, ivalid); pblock->GetValue (turn_keep_convex, t, keepConvex, ivalid); pblock->GetValue (turn_limit_size, t, limitSize, ivalid); if (limitSize) pblock->GetValue (turn_max_size, t, maxdeg, ivalid); pblock->GetValue (turn_planar, t, keepPlanar, ivalid); if (keepPlanar) { pblock->GetValue (turn_thresh, t, planarThresh, ivalid); planarThresh = cosf (planarThresh); } pblock->GetValue (turn_eliminate_collinear, t, elimCollin, ivalid); DWORD flags=0; if (selConv != 1) { flags = CONVERT_KEEPSEL; if (useSoftSel) flags |= CONVERT_USESOFTSEL; } ConvertPatchToPoly (obj->patch, mm, flags); if (maxdeg) mm.RestrictPolySize (maxdeg); if (keepConvex) mm.MakeConvex (); if (keepPlanar) mm.MakePlanar (planarThresh); if (elimCollin) mm.EliminateCollinearVerts (); switch (obj->patch.selLevel) { case PATCH_VERTEX: mm.selLevel = MNM_SL_VERTEX; break; case PATCH_EDGE: mm.selLevel = MNM_SL_EDGE; break; case PATCH_PATCH: mm.selLevel = MNM_SL_FACE; break; default: mm.selLevel = MNM_SL_OBJECT; break; } }
void SymmetryMod::RemovePolySpurs (MNMesh & mesh) { // Make sure we don't have any "spurs". for (int i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) continue; if (mesh.vedg[i].Count() != 1) continue; int vid = i; while ((!mesh.v[vid].GetFlag (MN_DEAD)) && (mesh.vedg[vid].Count() == 1)) { int edge = mesh.vedg[vid][0]; int otherEnd = mesh.e[edge].OtherVert (vid); mesh.RemoveSpur (edge); // The other end might be a tip of a spur now: vid = otherEnd; if (vid == i) { // shouldn't happen - extra check to prevent loops. DbgAssert (0); break; } } } }
float EditFaceDataModData::FaceValue (int faceID) { if (faceID<0) return 0.0f; if (faceID>mFacesAffected.GetSize()) return 0.0f; if (mFacesAffected[faceID]) return mtNewFaceValues[faceID]; IFaceDataMgr *pFDMgr = NULL; if (mpCacheMesh && (faceID < mpCacheMesh->numFaces)) { // Get the face data manager from the mesh: pFDMgr = static_cast<IFaceDataMgr*>(mpCacheMesh->GetInterface (FACEDATAMGR_INTERFACE)); } if (mpCacheMNMesh && (faceID < mpCacheMNMesh->numf)) { // Get the face data manager from the mesh: pFDMgr = static_cast<IFaceDataMgr*>(mpCacheMNMesh->GetInterface (FACEDATAMGR_INTERFACE)); } if (pFDMgr == NULL) return 0.0f; SampleFaceData* fdc = dynamic_cast<SampleFaceData*>(pFDMgr->GetFaceDataChan( FACE_MAXSAMPLEUSE_CLSID )); if (!fdc) return 0.0f; float val; if (!fdc->GetValue (faceID, val)) return 0.0f; return val; }
void PolyOpExtrudeAlongSpline::Do (MNMesh & mesh) { if (mpSpline == NULL) return; Tab<Matrix3> tTransforms; theFrenetFinder.ConvertPathToFrenets (mpSpline, mSplineXfm, tTransforms, mSegments, mAlign?true:false, mRotation); // Apply taper and twist to transforms: float denom = float(tTransforms.Count()-1); for (int i=1; i<tTransforms.Count(); i++) { float amount = float(i)/denom; // This equation taken from Taper modifier: float taperAmount = 1.0f + amount*mTaper + mTaperCurve*amount*(1.0f-amount); if (taperAmount != 1.0f) { // Pre-scale matrix by taperAmount. tTransforms[i].PreScale (Point3(taperAmount, taperAmount, taperAmount)); } if (mTwist != 0.0f) { float twistAmount = mTwist * amount; tTransforms[i].PreRotateZ (twistAmount); } } // Note: // If there are multiple face clusters, the first call to ExtrudeFaceClusterAlongPath // will bring mesh.numf and fClust.clust.Count() out of synch - fClust isn't updated. // So we fix that here. MNFaceClusters fClust (mesh, MN_USER); for (i=0; i<fClust.count; i++) { if (mesh.ExtrudeFaceClusterAlongPath (tTransforms, fClust, i, mAlign?true:false)) { if (i+1<fClust.count) { // New faces not in any cluster. int oldnumf = fClust.clust.Count(); fClust.clust.SetCount (mesh.numf); for (int j=oldnumf; j<mesh.numf; j++) fClust.clust[j] = -1; } } } }
void EditPolyData::ApplyAllOperations (MNMesh & mesh) { #ifdef __DEBUG_PRINT_EDIT_POLY DebugPrint (_T("EditPolyData::ApplyAllOperations\n")); #endif if (mpOpList) { // Preallocate if possible. (Upon first application, this will do nothing.) PolyOperationRecord* pOpRec = NULL; int newFaces(0), newVertices(0), newEdges(0); Tab<int> newMapVertices; newMapVertices.SetCount (mesh.numm + NUM_HIDDENMAPS); for (int mp=-NUM_HIDDENMAPS; mp<mesh.numm; mp++) newMapVertices[mp+NUM_HIDDENMAPS] = 0; for (pOpRec=mpOpList; pOpRec != NULL; pOpRec=pOpRec->Next()) { newFaces += pOpRec->Operation()->NewFaceCount(); newVertices += pOpRec->Operation()->NewVertexCount(); newEdges += pOpRec->Operation()->NewEdgeCount (); for (int mp=-NUM_HIDDENMAPS; mp<mesh.numm; mp++) { if (mesh.M(mp)->GetFlag (MN_DEAD)) continue; newMapVertices[mp+NUM_HIDDENMAPS] += pOpRec->Operation()->NewMapVertexCount(mp); } } mesh.VAlloc (mesh.numv + newVertices); mesh.EAlloc (mesh.nume + newEdges); mesh.FAlloc (mesh.numf + newFaces); for (int mp=-NUM_HIDDENMAPS; mp<mesh.numm; mp++) { MNMap *map = mesh.M(mp); if (map->GetFlag (MN_DEAD)) continue; map->VAlloc (map->numv + newMapVertices[mp+NUM_HIDDENMAPS]); map->FAlloc (map->numf + newFaces); } for (pOpRec=mpOpList; pOpRec != NULL; pOpRec=pOpRec->Next()) { #ifdef __DEBUG_PRINT_EDIT_POLY DebugPrint (_T("EditPolyData::Applying %s\n"), pOpRec->Operation()->Name()); #endif pOpRec->Operation()->SetUserFlags (mesh); bool ret = pOpRec->Operation()->Apply (mesh, pOpRec->LocalData()); if (ret && pOpRec->Operation()->CanDelete()) mesh.CollapseDeadStructs (); } } }
//ModifyObject will do all the work in a full modifier //This includes casting objects to their correct form, doing modifications //changing their parameters, etc void ProjectionHolderUVW::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { ObjectWrapper object; object.Init(t,*os,false, ObjectWrapper::allEnable, ObjectWrapper::triObject); if( object.IsEmpty() ) return; // Check topology if( object.NumFaces() != mData.mFaces.Count() ) return; for( int i=0; i<object.NumFaces(); i++ ) { GenFace face = object.GetFace(i); if( face.numVerts != mData.mFaces[i].numVerts ) return; } if( mData.miMapChannel != VERTEX_CHANNEL_NUM ) { // Check Channel Support if( !object.GetChannelSupport(mData.miMapChannel) ) object.SetChannelSupport( mData.miMapChannel, true ); object.SetNumMapVerts( mData.miMapChannel, mData.mP3Data.Count() ); for( int i=0; i<mData.mP3Data.Count(); i++ ) object.SetMapVert( mData.miMapChannel, i, mData.mP3Data[i] ); for( int i=0; i<mData.mFaces.Count(); i++ ) { object.SetMapFace( mData.miMapChannel, i, mData.mFaces[i] ); // Material ID Support if( mData.mDoMaterialIDs ) object.SetMtlID(i, mData.mMatID[i] ); } os->obj->PointsWereChanged(); } else { object.SetNumVerts( mData.mP3Data.Count() ); for( int i=0; i<mData.mP3Data.Count(); i++ ) object.SetVert( i, mData.mP3Data[i] ); for( int i=0; i<mData.mFaces.Count(); i++ ) { object.SetFace( i, mData.mFaces[i] ); // Material ID Support if( mData.mDoMaterialIDs ) object.SetMtlID(i, mData.mMatID[i] ); } os->obj->PointsWereChanged(); if( object.Type() == ObjectWrapper::polyObject ) { MNMesh *poly = object.GetPolyMesh(); if( poly ) poly->FillInMesh(); } else if( object.Type() == ObjectWrapper::triObject ) { Mesh *mesh = object.GetTriMesh(); if( mesh ) mesh->InvalidateTopologyCache(); } } Interval iv; iv = FOREVER; iv &= mData.mSrcInterval; if( mData.miMapChannel > 0 ) iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM); else if( mData.miMapChannel == VERTEX_CHANNEL_NUM ) { iv &= os->obj->ChannelValidity(t,GEOM_CHAN_NUM); iv &= os->obj->ChannelValidity(t,TOPO_CHAN_NUM); } else iv &= os->obj->ChannelValidity(t,VERT_COLOR_CHAN_NUM); if( mData.miMapChannel > 0 ) os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv); else if( mData.miMapChannel == VERTEX_CHANNEL_NUM ) { os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); os->obj->UpdateValidity(TOPO_CHAN_NUM,iv); } else os->obj->UpdateValidity(VERT_COLOR_CHAN_NUM,iv); }
void MeshTopoData::ApplyMapping(MNMesh &mesh, int mapChannel) { // allocate texture verts. Setup tv faces into a parallel // topology as the regular faces int numMaps = mesh.MNum (); if (mapChannel >= numMaps) { mesh.SetMapNum(mapChannel+1); mesh.InitMap(mapChannel); } MNMapFace *tvFace = mesh.M(mapChannel)->f; if (!tvFace) { mesh.InitMap(mapChannel); tvFace = mesh.M(mapChannel)->f; } int tvFaceCount = mesh.FNum(); if (mesh.selLevel!=MNM_SL_FACE) { //copy into mesh struct for (int k=0; k<tvFaceCount; k++) { if (k < TVMaps.f.Count()) { for (int m = 0; m< TVMaps.f[k]->count; m++) tvFace[k].tv[m] = TVMaps.f[k]->t[m]; } else { for (int m = 0; m< TVMaps.f[k]->count; m++) tvFace[k].tv[m] = 0; } } //match verts mesh.M(mapChannel)->setNumVerts( TVMaps.v.Count()); Point3 *tVerts = mesh.M(mapChannel)->v; for ( int k=0; k<TVMaps.v.Count(); k++) { tVerts[k] = GetTVVert(k); } } else { //copy into mesh struct //check if mesh has existing tv faces int offset = mesh.M(mapChannel)->VNum(); int current = 0; BitArray s; mesh.getFaceSel(s); for (int k=0; k<tvFaceCount; k++) { //copy if face is selected if (s[k]==1) { for (int m = 0; m< TVMaps.f[k]->count; m++) tvFace[k].tv[m] = TVMaps.f[k]->t[m] + offset; } } //add our verts for ( int k=0; k<TVMaps.v.Count(); k++) mesh.M(mapChannel)->NewVert( GetTVVert(k)); } mesh.M(mapChannel)->CollapseDeadVerts(mesh.f); }
void MeshTopoData::SetCache(MNMesh &mesh, int mapChannel) { FreeCache(); this->mnMesh = new MNMesh(mesh); TVMaps.channel = mapChannel; BitArray s; mesh.getFaceSel(s); mesh.getFaceSel(mFSelPrevious); if ( (mesh.selLevel==MNM_SL_FACE) && (s == 0) ) { TVMaps.SetCountFaces(0); TVMaps.v.SetCount(0); TVMaps.FreeEdges(); TVMaps.FreeGeomEdges(); mVSel.SetSize(0); mESel.SetSize(0); mFSel.SetSize(0); mGESel.SetSize(0); mGVSel.SetSize(0); return; } //get from mesh based on cahne int numMaps = mesh.MNum (); MNMapFace *tvFace=NULL; Point3 *tVerts = NULL; if (mapChannel >= numMaps) { } else { tvFace = mesh.M(mapChannel)->f; tVerts = mesh.M(mapChannel)->v; } if (mesh.selLevel!=MNM_SL_FACE) { //copy into our structs TVMaps.SetCountFaces(mesh.FNum()); if (tVerts) { TVMaps.v.SetCount(mesh.M(mapChannel)->VNum()); mVSel.SetSize(mesh.M(mapChannel)->VNum()); } else { TVMaps.v.SetCount(mesh.VNum()); mVSel.SetSize(mesh.VNum()); } TVMaps.geomPoints.SetCount(mesh.VNum()); for (int j=0; j<TVMaps.f.Count(); j++) { TVMaps.f[j]->flags = 0; int fct; fct = mesh.f[j].deg; if (mesh.f[j].GetFlag(MN_DEAD)) fct = 0; if (fct > 0) { TVMaps.f[j]->t = new int[fct]; TVMaps.f[j]->v = new int[fct]; } else { TVMaps.f[j]->t = NULL; TVMaps.f[j]->v = NULL; } if (tvFace == NULL) { for (int k=0; k < fct;k++) TVMaps.f[j]->t[k] = 0; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = mesh.f[j].material; TVMaps.f[j]->flags = 0; TVMaps.f[j]->count = fct; for (int k = 0; k < fct; k++) { int index = mesh.f[j].vtx[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = mesh.v[index].p; } } else { for (int k=0; k < fct;k++) TVMaps.f[j]->t[k] = tvFace[j].tv[k]; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = mesh.f[j].material; TVMaps.f[j]->flags = 0; TVMaps.f[j]->count = fct; for (int k = 0; k < fct; k++) { int index = mesh.f[j].vtx[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = mesh.v[index].p; } } } for ( int j=0; j<TVMaps.v.Count(); j++) { TVMaps.v[j].SetFlag(0); if (tVerts) TVMaps.v[j].SetP(tVerts[j]); else TVMaps.v[j].SetP(Point3(.0f,0.0f,0.0f)); TVMaps.v[j].SetInfluence(0.0f); TVMaps.v[j].SetControlID(-1); } if (tvFace == NULL) BuildInitialMapping(&mesh); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count()); TVMaps.mSystemLockedFlag.ClearAll(); } else { //copy into our structs TVMaps.SetCountFaces(mesh.FNum()); int tvVertCount = 0; if (mapChannel < numMaps) { tvVertCount = mesh.M(mapChannel)->VNum(); } TVMaps.v.SetCount(tvVertCount); mVSel.SetSize(tvVertCount); TVMaps.geomPoints.SetCount(mesh.VNum()); BitArray bs; mesh.getFaceSel(bs); for (int j=0; j<TVMaps.f.Count(); j++) { TVMaps.f[j]->flags = 0; int fct; fct = mesh.f[j].deg; if (mesh.f[j].GetFlag(MN_DEAD)) fct = 0; if (fct > 0) { TVMaps.f[j]->t = new int[fct]; TVMaps.f[j]->v = new int[fct]; } else { TVMaps.f[j]->t = NULL; TVMaps.f[j]->v = NULL; } if (tvFace == NULL) { for (int k=0; k < fct;k++) TVMaps.f[j]->t[k] = 0; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = mesh.f[j].material; TVMaps.f[j]->count = fct; if (bs[j]) TVMaps.f[j]->flags = 0; else TVMaps.f[j]->flags = FLAG_DEAD; for (int k = 0; k < fct; k++) { int index = mesh.f[j].vtx[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = mesh.v[index].p; } } else { for (int k=0; k < fct;k++) TVMaps.f[j]->t[k] = tvFace[j].tv[k]; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = mesh.f[j].material; TVMaps.f[j]->count = fct; if (bs[j]) TVMaps.f[j]->flags = 0; else TVMaps.f[j]->flags = FLAG_DEAD; for ( int k = 0; k < fct; k++) { int index = mesh.f[j].vtx[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = mesh.v[index].p; } } } for (int j=0; j<TVMaps.v.Count(); j++) { if (tVerts) TVMaps.v[j].SetP(tVerts[j]); else TVMaps.v[j].SetP(Point3(0.0f,0.0f,0.0f)); //check if vertex for this face selected TVMaps.v[j].SetInfluence(0.0f); TVMaps.v[j].SetControlID(-1); } if (tvFace == NULL) BuildInitialMapping(&mesh); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count()); TVMaps.mSystemLockedFlag.SetAll(); for (int j=0; j<TVMaps.f.Count(); j++) { if (!(TVMaps.f[j]->flags & FLAG_DEAD)) { int a; for (int k =0 ; k < TVMaps.f[j]->count;k++) { a = TVMaps.f[j]->t[k]; TVMaps.v[a].SetFlag(0); TVMaps.mSystemLockedFlag.Set(a,FALSE); } } } } }
void FaceDataToColorMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { if (mDisabled) return; IFaceDataMgr* pFDMgr = NULL; // We can work with Face Data in a couple different object types: TriObject *pTri = NULL; PolyObject *pPoly = NULL; Mesh *pMesh = NULL; MNMesh *pMNMesh = NULL; int numFaces = 0; if (os->obj->IsSubClassOf(triObjectClassID)) { pTri = (TriObject*)os->obj; pMesh = &(pTri->GetMesh()); numFaces = pMesh->getNumFaces(); // Get the face-data manager from the incoming object pFDMgr = static_cast<IFaceDataMgr*>(pMesh->GetInterface( FACEDATAMGR_INTERFACE )); } else if (os->obj->IsSubClassOf(polyObjectClassID)) { pPoly = (PolyObject*)os->obj; pMNMesh = &pPoly->GetMesh(); numFaces = pMNMesh->numf; // Get the face-data manager from the incoming object pFDMgr = static_cast<IFaceDataMgr*>(pMNMesh->GetInterface( FACEDATAMGR_INTERFACE )); } if (pFDMgr == NULL) return; //Get our parameters int channel; float r, g, b; Interval ourValidity = os->obj->ChannelValidity (t, TOPO_CHAN_NUM); mpParams->GetValue (pb_channel, t, channel, ourValidity); mpParams->GetValue (pb_red, t, r, ourValidity); mpParams->GetValue (pb_green, t, g, ourValidity); mpParams->GetValue (pb_blue, t, b, ourValidity); // Get at our SampleFaceData: SampleFaceData *pFaceData = dynamic_cast<SampleFaceData *>(pFDMgr->GetFaceDataChan (FACE_MAXSAMPLEUSE_CLSID)); // Apply the colors - different code depending on object type: if (pMesh) { pMesh->setMapSupport (-channel, true); pMesh->setNumMapVerts (-channel, 3*numFaces); TVFace *pFace = pMesh->mapFaces(-channel); VertColor *pColor = pMesh->mapVerts (-channel); int maxFaceData = pFaceData ? pFaceData->Count() : 0; for (int i=0; i<numFaces; i++) { for (int j=0; j<3; j++) { int k = i*3+j; pFace[i].t[j] = k; if (i<maxFaceData) { float fdValue = pFaceData->data[i]; VertColor val; val.x = r*fdValue; if (val.x < 0) val.x = 0.0f; if (val.x > 1) val.x = 1.0f; val.y = g*fdValue; if (val.y < 0) val.y = 0.0f; if (val.y > 1) val.y = 1.0f; val.z = b*fdValue; if (val.z < 0) val.z = 0.0f; if (val.z > 1) val.z = 1.0f; pColor[k] = val; } else pColor[k] = VertColor(0,0,0); } } } if (pMNMesh) { if ((channel == 0) && (pMNMesh->numm == 0)) pMNMesh->SetMapNum (1); pMNMesh->M(-channel)->ClearFlag (MN_DEAD); pMNMesh->M(-channel)->setNumFaces (numFaces); // Precount the number of map vertices we need: int numColors = 0; for (int i=0; i<numFaces; i++) { if (pMNMesh->f[i].GetFlag (MN_DEAD)) continue; numColors += pMNMesh->f[i].deg; } pMNMesh->M(-channel)->setNumVerts (numColors); MNMapFace *pFace = pMNMesh->M(-channel)->f; VertColor *pColor = pMNMesh->M(-channel)->v; int maxFaceData = pFaceData ? pFaceData->Count() : 0; for (int i=0, k = 0; i<numFaces; i++) { if (pMNMesh->f[i].GetFlag (MN_DEAD)) continue; pFace[i].SetSize (pMNMesh->f[i].deg); for (int j=0; j<pMNMesh->f[i].deg; j++) { pFace[i].tv[j] = k; if (i<maxFaceData) { float fdValue = pFaceData->data[i]; VertColor val; val.x = r*fdValue; if (val.x < 0) val.x = 0.0f; if (val.x > 1) val.x = 1.0f; val.y = g*fdValue; if (val.y < 0) val.y = 0.0f; if (val.y > 1) val.y = 1.0f; val.z = b*fdValue; if (val.z < 0) val.z = 0.0f; if (val.z > 1) val.z = 1.0f; pColor[k] = val; } else pColor[k] = VertColor(0,0,0); k++; } } } os->obj->SetChannelValidity (VERT_COLOR_CHAN_NUM, ourValidity); }
//------------------------------ bool MorphControllerCreator::initializeChannelGeometry( morphChannel* channel, Object* geometryObject ) { if ( !channel || !geometryObject ) { return false; } Class_ID geometryObjectClassId = geometryObject->ClassID(); MNMesh* polyMesh = 0; Mesh* triangleMesh = 0; if ( (geometryObjectClassId == EPOLYOBJ_CLASS_ID) || (geometryObjectClassId.PartA() == POLYOBJ_CLASS_ID) ) { polyMesh = &((PolyObject*)geometryObject)->GetMesh(); } else if ( (geometryObjectClassId.PartA() == TRIOBJ_CLASS_ID) || (geometryObjectClassId.PartA() == EDITTRIOBJ_CLASS_ID ) ) { triangleMesh = &((TriObject*)geometryObject)->GetMesh(); } if ( !polyMesh && !triangleMesh ) { // unsupported object type return true; } // Verify that the COLLADA source size matches the original mesh's vertex count int vertexCount = polyMesh ? polyMesh->VNum() : triangleMesh->numVerts; if (vertexCount != channel->mp->cache.count) { return false; } // Set the channel's name and the necessary flags channel->mName = getObjectNameByObject(geometryObject).c_str(); channel->mInvalid = false; channel->mActive = true; channel->mModded = true; // Allocate the channel's buffers and fill them with the relative vertex positions channel->AllocBuffers(vertexCount, vertexCount); channel->mSel.SetSize(vertexCount); channel->mSel.ClearAll(); channel->mNumPoints = vertexCount; if ( polyMesh ) { for (int i = 0; i < vertexCount; ++i) { channel->mPoints[i] = polyMesh->V( i )->p; channel->mDeltas[i] = (channel->mPoints[i] - channel->mp->cache.points[i]) / 100.0f; channel->mSel.Set(i, false); channel->mWeights[i] = 1.0f; // Not too sure of what the value should be here. } } else { for (int i = 0; i < vertexCount; ++i) { channel->mPoints[i] = triangleMesh->verts[ i ]; channel->mDeltas[i] = (channel->mPoints[i] - channel->mp->cache.points[i]) / 100.0f; channel->mSel.Set(i, false); channel->mWeights[i] = 1.0f; // Not too sure of what the value should be here. } } // Update all the UI stuff. Important? Must it be done for every channel? channel->mp->NotifyDependents(FOREVER,(PartID) PART_ALL,REFMSG_CHANGE); channel->mp->NotifyDependents(FOREVER,(PartID) PART_ALL,REFMSG_SUBANIM_STRUCTURE_CHANGED); channel->mp->Update_channelFULL(); channel->mp->Update_channelParams(); return true; }
IGeometryChecker::ReturnVal MissingUVCoordinatesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val) { val.mIndex.ZeroCount(); if(IsSupported(nodeToCheck)) { LARGE_INTEGER ups,startTime; QueryPerformanceFrequency(&ups); QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog bool compute = true; bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active! UVWChannel uvmesh; ObjectState os = nodeToCheck->EvalWorldState(t); Object *obj = os.obj; if(os.obj->IsSubClassOf(triObjectClassID)) { TriObject *tri = dynamic_cast<TriObject *>(os.obj); if(tri) { BitArray arrayOfVertices; arrayOfVertices.SetSize(tri->mesh.numVerts); arrayOfVertices.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels = tri->mesh.getNumMaps(); int index; for(int i=0;i<numChannels;++i) { if(tri->mesh.mapSupport(i)) { MeshMap *map = &tri->mesh.Map(i); if(map->getNumVerts()>0 &&map->getNumFaces()>0) { returnval= TypeReturned(); int numFaces = map->getNumFaces(); TVFace * tvFaces = map->tf; UVVert * uvVerts= map->tv; #pragma omp parallel for for(int faceIndex =0;faceIndex<numFaces;++faceIndex) { if(compute) { TVFace& tvFace = tvFaces[faceIndex]; Point3 tv = uvVerts[tvFace.t[0]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[0]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[tvFace.t[1]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[1]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[tvFace.t[2]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[2]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } if(checkTime==true) { #pragma omp critical { DialogChecker::Check(checkTime,compute,numFaces,startTime,ups); } } } } } } } if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfVertices.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfVertices[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } else if(os.obj->IsSubClassOf(polyObjectClassID)) { PolyObject *poly = dynamic_cast<PolyObject *>(os.obj); if(poly) { BitArray arrayOfVertices; arrayOfVertices.SetSize(poly->GetMesh().numv); arrayOfVertices.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels= poly->GetMesh().MNum(); int index; for(int i=0;i<numChannels;++i) { if(poly->GetMesh().M(i)) { MNMesh *mesh = &(poly->GetMesh()); MNMap *mnmap = mesh->M(i); if(mnmap&&mnmap->numv>0&&mnmap->numf>0) { returnval= TypeReturned(); int numFaces = mnmap->numf; #pragma omp parallel for for(int faceIndex =0;faceIndex<numFaces;++faceIndex) { if(compute) { Point3 tv; int a,b,c; MNMapFace *face = mnmap->F(faceIndex); UVVert * uvVerts= mnmap->v; for(int j=0;j<(face->deg);++j) { if(j==(face->deg-2)) { a = j; b = j+1; c = 0; } else if(j==(face->deg-1)) { a = j; b = 0; c = 1; } else { a = j; b = j+1; c = j+2; } tv = uvVerts[face->tv[a]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[a]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[face->tv[b]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[b]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[face->tv[c]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[c]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } if(checkTime==true) { #pragma omp critical { DialogChecker::Check(checkTime,compute,numFaces,startTime,ups); } } } } } } } } if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfVertices.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfVertices[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } } return IGeometryChecker::eFail; }
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); }