[Closed] Extrude Faces?
How can I extrude faces in the 3dsmax SDK?
In maxscript, I would do (just as an example):
obj = box()
convertToMesh obj
meshop.extrudeFaces obj #{1..obj.faces.count} 5.0 -1.0
in C++, the mesh.extrudeFaces method only takes a single parameter, a boolean. The descriptions states it extrudes the selected faces.
pubic : void Mesh::ExtrudeFaces(BOOL doFace = 1)
* Extrudes the selected faces. Not that this is just a topological change. The new extruded faces do not change position but are left on top of the original faces.
\param doFace
if TRUE the faces are extruded. if FALSE then the selected edges are extruded.
File: mesh.h
Therefore, how can I “select” the faces I want to extrude prior to calling this method?
Thanks!
Therefore, how can I “select” the faces I want to extrude prior to calling this method?
the extrudefaces method creates all new geometry needed to create the extrude but doesn’t do any of the actual shifting of the verts.
So this is how I would probably do it where faces is a bitarray of the faces you want to extrude or use a MeshDelta object
mesh->faceSel = faces;
mesh->ExtrudeFaces();
int nVerts=mesh->getNumVerts();
if (nVerts != 0)
{
// collect the verts in the "extruded" faces
BitArray verts (nVerts);
for (int i = 0; i < mesh->getNumFaces(); ++i)
{
if (!mesh->faceSel[i]) continue;
Face *f = &mesh->faces[i];
for (int j = 0; j < 3; j++) verts.Set(f->v[j]);
}
// do the shift
for (int i = 0; i < mesh->nVerts; ++i)
{
if(verts [ i])
{
// compute the shift.... for each vert
}
}
}
Hello,
How would I get the BitArray of the faces I would like to extrude?
For example in maxscript:
faces = #{1…10}
Thanks!
how do you know which faces you want to extrude ? from the current selection, an array of face indices, all the faces of a material id, or a smoothing group etc.
Sorry, I mean, how would I go about creating the BitArray of face indices by range. In maxscript you do:
#{startIndice..endIndice}
For instance, let’s say I wanted to convert #{5…15) to C++
Would it be something like this?
BitArray faces(10);
faces.shift(RIGHT_BITSHIFT, 5);
How do I do this in C++:
mesh.faceSel = #{5…15} // Specify a range of face indices to select
That is my question. Sorry if I’m not making any sense. I’m a noob at the SDK but not at maxscript. Thanks for your help.
i’ve played a lot with c++ bitarrays… the simplest, fastest, and universal way to get/set bits is a simple iteration:
BitArray bits(count);
for (int k=start; k < count && k <= end; k++) bits.Set(k);
where bit index is zero based instead of mxs
i don’t have my pro computer around… but i remember that my extrude faces code i stole from meshop.cpp example in max sdk and it works for me
from fextrude.cpp in the modifiers project in the samples
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
Mesh &mesh = tobj->GetMesh();
Interval iv = FOREVER;
float a, s;
Point3 pt, center;
int c;
pblock->GetValue(PB_AMOUNT,t,a,iv);
pblock->GetValue(PB_SCALE,t,s,iv);
pblock->GetValue(PB_CENTER,t,c,iv);
base->GetValue(t,&pt,iv,CTRL_ABSOLUTE);
// Extrude the faces -- this just creates the new faces
mesh.ExtrudeFaces();
// Build normals of selected faces only
Tab<Point3> normals;
if (!c) {
normals.SetCount(mesh.getNumVerts());
for (int i=0; i<mesh.getNumVerts(); i++) {
normals[i] = Point3(0,0,0);
}
for (int i=0; i<mesh.getNumFaces(); i++) {
if (mesh.faceSel[i]) {
Point3 norm =
(mesh.verts[mesh.faces[i].v[1]]-mesh.verts[mesh.faces[i].v[0]]) ^
(mesh.verts[mesh.faces[i].v[2]]-mesh.verts[mesh.faces[i].v[1]]);
for (int j=0; j<3; j++) {
normals[mesh.faces[i].v[j]] += norm;
}
}
}
for (int i=0; i<mesh.getNumVerts(); i++) {
normals[i] = Normalize(normals[i]);
}
} else {
// Compute the center point
base->GetValue(t,¢er,iv,CTRL_ABSOLUTE);
}
// Mark vertices used by selected faces
BitArray sel;
sel.SetSize(mesh.getNumVerts());
for (int i=0; i<mesh.getNumFaces(); i++) {
if (mesh.faceSel[i]) {
for (int j=0; j<3; j++) sel.Set(mesh.faces[i].v[j],TRUE);
}
}
// Move selected verts
for (int i=0; i<mesh.getNumVerts(); i++) {
if (sel[i]) {
if (!c) {
mesh.verts[i] += normals[i]*a;
} else {
Point3 vect = Normalize((mesh.verts[i] * (*mc.tm))
- center);
mesh.verts[i] += vect*a;
}
}
}
// Scale verts
if (s!=100.0f) {
s /= 100.0f;
AdjEdgeList ae(mesh);
AdjFaceList af(mesh,ae);
FaceClusterList clust(mesh.faceSel,af);
// Make sure each vertex is only scaled once.
BitArray done;
done.SetSize(mesh.getNumVerts());
// scale each cluster independently
for (int i=0; (DWORD)i<clust.count; i++) {
// First determine cluster center
Point3 cent(0,0,0);
int ct=0;
for (int j=0; j<mesh.getNumFaces(); j++) {
if (clust[j]==(DWORD)i) {
for (int k=0; k<3; k++) {
cent += mesh.verts[mesh.faces[j].v[k]];
ct++;
}
}
}
if (ct) cent /= float(ct);
// Now scale the cluster about its center
for (int j=0; j<mesh.getNumFaces(); j++) {
if (clust[j]==(DWORD)i) {
for (int k=0; k<3; k++) {
int index = mesh.faces[j].v[k];
if (done[index]) continue;
done.Set(index);
mesh.verts[index] =
(mesh.verts[index]-cent)*s + cent;
}
}
}
}
}
mesh.InvalidateTopologyCache ();
os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);
}