Notifications
Clear all

[Closed] The Quick 'n' Dirty Way to extend MXS with the SDK

requirements…

3ds max
sdk installed for the max version you want to extend for
[and the correct version of microsoft visual studio]( http://help.autodesk.com/view/3DSMAX/2015/ENU/?guid=__files_GUID_6E179A56_5552_4D0B_BA61_BBD37B9E52DB_htm) 

1. go to  \Autodesk\<max version> SDK\maxsdk\samples\maxscript\mxsagni
2. double click on mxsagni.vcproj this should open the mxsagni project in visual studio
3. in the solution configurations drop down in the main toobar select [b]Release [/b]from the menu (should be displaying Debug when you start)  if you doing a x64 build you'll need to change Solution Platforms dropdown from Win32 to x64.
4. From the solution explorer/Source Files open the file avg_DLX.cpp
5. Copy the following Code 
 def_visible_primitive(MtlPreviewToBitmap, "MtlPreviewToBitmap");
      
    Value* MtlPreviewToBitmap_cf(Value** arg_list, int count)
    {
    	check_arg_count(MtlPreviewToBitmap, 2, count);
    
    	MtlBase* mb = arg_list[0]->to_mtlbase();
    	int sz = arg_list[1]->to_int();
    
    	PStamp *ps = mb->CreatePStamp(sz,1);
    	if(ps)
    	{
    		int d = PSDIM(sz);
    		int scanw = ByteWidth(d);
    		int nb = scanw*d;
    
    		UBYTE *buf = new UBYTE[nb + sizeof(BITMAPINFOHEADER)];
    		if(!buf)
    			 &undefined;
    
    // get the image data
    
    		ps->GetImage(&buf[sizeof(BITMAPINFOHEADER)]);
    		
    // and create the header info		
    		
    		BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)buf;
    		bih->biSize = sizeof(BITMAPINFOHEADER);
    		bih->biWidth = d; 
    		bih->biHeight = d; 
    		bih->biPlanes = 1; 
    		bih->biBitCount = 24;
    		bih->biCompression = BI_RGB;
    		bih->biSizeImage = 0;
    		
    		Bitmap *map = TheManager->Create((PBITMAPINFO)buf);
    		delete [] buf;
    
    		if(map)
    		{
    			one_typed_value_local(MAXBitMap* mbm);
    			vl.mbm = new MAXBitMap();
    			vl.mbm->bi.CopyImageInfo(&map->Storage()->bi);
    			vl.mbm->bi.SetFirstFrame(0);
    			vl.mbm->bi.SetLastFrame(0);
    			vl.mbm->bi.SetName("");
    			vl.mbm->bi.SetDevice("");
    			if(vl.mbm->bi.Type() > BMM_TRUE_64)
    				vl.mbm->bi.SetType(BMM_TRUE_64);
    			vl.mbm->bm = map;
    			return_value(vl.mbm);
    		}
    	}
    	return &undefined;
    }

or other more useful bits of code just before other stuff can be found here

//  =================================================
    //  Spline methods
    //  =================================================
6. press F7 to build the solution
7. if the Output window displays the following all is good

========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Otherwise there are compiler issues, eg a coding syntax error or linker errors.
8. goto the folder Autodesk<Max Version> SDK\exe\stdplugs and copy the file MXSAgni.dlx to \Autodesk<Max Version>\stdplugs. You can back up the original or rename it to MXSAgni.bak or something.
9. restart max
10. run the following from the MXS listener.

display (MtlPreviewToBitmap (getMeditMaterial 1) 0)
11. remember to add [b]MXSAgni.dlx [/b]to any redistributables.
5 Replies

Thank you.

Klvnk, thank you! I will try this! Shouldn’t you use smth like loadscript, filin or smth like this?

the best extending functions by a country mile are

def_struct_primitive(polyop_getMapVertsUsingVert, polyop, "getMapVertsUsingVert");

// <bitarray> polyop.getMapVertsUsingVert <Poly poly> <int mapChannel> <vertlist>
  
  Value* polyop_getMapVertsUsingVert_cf(Value** arg_list, int arg_count)
  {
  // the usual arg check
  
  	check_arg_count(getMapVertsUsingVert, 3, arg_count);
  
  // get the poly mesh
  
  	MNMesh* pmesh = get_polyForValue(arg_list[0], MESH_READ_ACCESS, NULL, getMapVertsUsingVert);
  
  	int channel = arg_list[1]->to_int();
  	checkMapChannel(pmesh,channel);
  
  // ok to access the map
  
  	MNMap* map = pmesh->M(channel);
  	int nVerts  = pmesh->numv;
  	int nMapVerts = map->numv;
  	int nMapFaces = map->numf;
  
  // create a new bitarray from input which could be a bitarray, int or array of ints
  
  	BitArray verts(nVerts);
  	ValueToBitArray(arg_list[2], verts, nVerts, GetString(IDS_VERTEX_INDEX_OUT_OF_RANGE));
  
  // create the return bitarray variable on the stack
  
  	one_typed_value_local(BitArrayValue* mapVerts);
  	vl.mapVerts = new BitArrayValue(nMapVerts);
  
  	for(int f=0; f < nMapFaces; f++)
  	{
  		MNFace*	face = pmesh->F(f);
  
  // skip over dead faces
  
  		if(face->GetFlag(MN_DEAD)) 
  			continue;
  
  		MNMapFace* mapface = map->F(f);
  
  		for(int j=0; j < face->deg; j++) 
  		{
  			if(verts[face->vtx[j]])
  			{
  				vl.mapVerts->bits.Set(mapface->tv[j]);
  				break; // should only be one per face
  			}
  		}
  	}
  	return_value(vl.mapVerts);
  }

and the mesh varient

//********************************************************************************************
  // meshop.getMapVertsUsingVert
  //<bitarray mapverts> meshop.getMapVertsUsingVert  <Mesh mesh\> <int mapChannel> <int vert>
 
  def_struct_primitive(meshop_getMapVertsUsingVert, meshop, "getMapVertsUsingVert");
  
  Value* meshop_getMapVertsUsingVert_cf(Value **arg_list, int count)
  {
  	check_arg_count(getMapVertsUsingVert, 3, count);
  
  // mesh
  
  	Mesh* mesh = get_meshForValue(arg_list[0], MESH_READ_ACCESS, NULL, getMapVertsUsingVert);
  
  // channel
  
  	int mapChannel = arg_list[1]->to_int();
  	range_check(mapChannel, -NUM_HIDDENMAPS, MAX_MESHMAPS-1, GetString(IDS_MESH_MAP_CHANNEL_OUT_OF_RANGE));
  	if(!mesh->mapSupport(mapChannel))
  		throw RuntimeError (GetString(IDS_MAP_SUPPORT_NOT_ENABLED_FOR_CHANNEL), Integer::intern(mapChannel));
  
  // vert
  
  	int	vert = arg_list[2]->to_int() - 1; // mxs to sdk
  	range_check(vert,0,(mesh->numVerts - 1), GetString(IDS_VERTEX_INDEX_OUT_OF_RANGE));
  
  // create the return bitarray variable on the stack
  
  	one_typed_value_local(BitArrayValue* mapVerts);
  	vl.mapVerts = new BitArrayValue(mesh->getNumMapVerts(mapChannel));
  	
  // get the pointer to the map faces
  
  	TVFace*	mapfaces = mesh->mapFaces(mapChannel);
  
  // for all the faces, find our vert, and tag the same "corner" in the map face
  
  	int nfaces = mesh->numFaces;
  	for(int i = 0; i < nfaces; ++i)
  	{
  		Face& geoface = mesh->faces[i]; // 
  		for(int j=0; j < 3; ++j) 
  		{
  			if(geoface.v[j] == vert)
  			{
  				vl.mapVerts->bits.Set(mapfaces[i].t[j]);
  				break; // should only be one per face
  			}
  		}
  	}
  	return_value(vl.mapVerts);
  }

Klunk, Thanks for this, very helpful.

Is there a way to return the collection of BitArrayValues? Say if I’d like to get all the mesh elements as an array of bitarrays. Is it even possible?
Thanks

upd Found the answer in this incredible thread. Thank you guys!