///////////////////////////////////////////////////////////////////// // Note: // The vertex color data that is used by the ModifyPolyObject // method was created based on this PolyObject's displayed // TriMesh (Mesh). This data is mapped back to the original // PolyMesh (MNMesh). The mapping relies on the same process // that was used by the method MNMesh::OutToTri() to generate // the Mesh. // Warning: // The mapping used in this method will need to be updated if // anything changes in the way MNMesh generates its displayed Mesh. // Author: // Wayne Catalfano // Date: // August 30, 2000 // /////////////////////////////////////////////////////////////////////// void ApplyVCMod::ModifyPolyObject(PolyObject* pPolyObj, TimeValue t) { static int calls = 0; iValid = FOREVER; Interval valid = GetValidity(t); MNMesh& mesh = pPolyObj->GetMesh(); if (mesh.MNum() < 1) mesh.SetMapNum (1); // get the vertex color map MNMap* pVCMap = mesh.M(0); // initialize to an all white map if necessary if (pVCMap->GetFlag(MN_DEAD)) mesh.InitMap(0); if (mixedVertexColors.Count() > 0) { pVCMap->setNumVerts (mesh.VNum()); pVCMap->setNumFaces (mesh.FNum()); // MNMesh keeps the vertices in the same order when it creates // the Mesh. The Mesh vertices Map directly back to the MNMesh // vertices in the same order. for (int i=0; i<mesh.VNum(); i++) { pVCMap->v[i] = i<mixedVertexColors.Count() ? Point3(mixedVertexColors[i]->r, mixedVertexColors[i]->g, mixedVertexColors[i]->b) : Point3(1.0f, 1.0f, 1.0f); } for (int i=0; i<mesh.FNum(); i++) { if (mesh.F(i)->GetFlag (MN_DEAD)) continue; pVCMap->F(i)->SetSize(mesh.F(i)->deg); for (int j=0; j<mesh.F(i)->deg;++j) { pVCMap->F(i)->tv[j] = mesh.F(i)->vtx[j]; } } } else if (faceColors.Count() > 0) { int numVCVerts = 0; for (int i=0; i<mesh.FNum(); i++) { if (mesh.F(i)->GetFlag (MN_DEAD)) continue; numVCVerts += mesh.F(i)->deg; } pVCMap->setNumVerts (numVCVerts); pVCMap->setNumFaces (mesh.FNum()); // This mapping process mimicks the process used to generate // the Mesh in the method MNMesh::OutToTri(). int faceVert = 0; int triFaceIndx = 0; BitArray faceVertSet; for (int i=0; i<mesh.FNum(); i++) { if (mesh.F(i)->GetFlag (MN_DEAD)) continue; pVCMap->F(i)->SetSize(mesh.F(i)->deg); faceVertSet.SetSize(mesh.F(i)->deg); faceVertSet.ClearAll(); int tnum = mesh.F(i)->TriNum()*3; Tab<int> triVerts; // The method MNFace::GetTriangles is at the heart of the // process used to map Mesh triangles back to MNMesh faces. mesh.F(i)->GetTriangles (triVerts); for (int j=0; j<tnum; j+=3) { for (int k=0; k<3; ++k) { int vertIndex = triVerts[j+k]; // check if we already added a vert for this index if (!faceVertSet[vertIndex]) { pVCMap->v[faceVert] = triFaceIndx<faceColors.Count() ? Point3(faceColors[triFaceIndx]->colors[k].r, faceColors[triFaceIndx]->colors[k].g, faceColors[triFaceIndx]->colors[k].b) : Point3(1.0f, 1.0f, 1.0f); pVCMap->F(i)->tv[vertIndex] = faceVert; faceVertSet.Set(vertIndex); faceVert++; } } ++triFaceIndx; } } } NotifyDependents(Interval(t,t), PART_VERTCOLOR & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE); NotifyDependents(Interval(t,t), PART_TOPO & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE); pPolyObj->UpdateValidity(VERT_COLOR_CHAN_NUM, valid); }
void ModifierPtex::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval valid = FOREVER; int uvw_channel = 0; if ( m_pblock->GetInt( UVW_TYPE ) == 0 ) { uvw_channel = m_pblock->GetInt( UVW_CHANNEL ); } if ( os->obj->IsSubClassOf( polyObjectClassID ) ) { PolyObject *polyObj = (PolyObject*)os->obj; MNMesh &mnMesh = polyObj->GetMesh(); bool has_map; if ( uvw_channel >= mnMesh.MNum() ) { mnMesh.SetMapNum( uvw_channel + 1 ); has_map = false; } else { has_map = mnMesh.M( uvw_channel )->GetFlag( MN_DEAD ) == false; } MNMap *mc = mnMesh.M( uvw_channel ); if ( has_map == false ) { mc->setNumFaces( mnMesh.numf ); for ( int i_f = 0; i_f < mnMesh.numf; i_f++ ) { mc->f[ i_f ].SetSize( mnMesh.f[ i_f ].deg ); } } if ( mc->GetFlag( MN_DEAD ) ) mc->ClearFlag( MN_DEAD ); unsigned int num_tverts = 0; for ( int i_f = 0; i_f < mnMesh.numf; i_f++ ) { num_tverts += mc->f[ i_f ].deg; } mc->setNumVerts( num_tverts ); unsigned int tvert_id = 0; for ( int i_f = 0; i_f < mnMesh.numf; i_f++ ) { unsigned int deg = mc->f[ i_f ].deg; for ( unsigned int i_v = 0; i_v < deg; i_v++ ) { mc->f[ i_f ].tv[ i_v ] = tvert_id; Point3 tv; if ( i_v == 0 ) tv = Point3( (float)i_f, 0.0f, 0.0f ); else if ( i_v == 1 ) tv = Point3( (float)i_f + 1.0f, 0.0f, 0.0f ); else if ( i_v == 2 ) tv = Point3( (float)i_f + 1.0f, 1.0f, 0.0f ); else tv = Point3( (float)i_f, 1.0f, 0.0f ); tv.z = 0.0f; mc->v[ tvert_id ] = tv; tvert_id++; } } } // Update all the caches etc Interval iv = LocalValidity(t); iv = iv & os->obj->ChannelValidity( t, GEOM_CHAN_NUM ); iv = iv & os->obj->ChannelValidity( t, TOPO_CHAN_NUM ); os->obj->UpdateValidity( TEXMAP_CHAN_NUM, iv ); }