// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #define EXPORT_GET_ALLOCATOR #pragma conform(forScope, push) #pragma conform(forScope, off) #define _CRT_SECURE_NO_DEPRECATE #include #include #include // Various MAX and MXS includes #include #include #include #include #include #include #include #include #include #include // define the new primitives using macros from SDK #include #undef _CRT_SECURE_NO_DEPRECATE #pragma conform(forScope, pop) #undef min #undef max #include "PO2RPO.h" #include "nel/misc/file.h" #include "nel/misc/common.h" #include "..\nel_patch_lib\rpo.h" #include "..\nel_mesh_lib\export_nel.h" #include "..\nel_mesh_lib\export_appdata.h" #include "nel/3d/zone.h" #include "nel/3d/zone_symmetrisation.h" #include "nel/3d/tile_bank.h" using namespace NLMISC; using namespace NL3D; using namespace std; /*===========================================================================*\ | Define our new functions | These will turn on texture map display at all levels for a given object \*===========================================================================*/ def_visible_primitive( set_steps, "SetRykolPatchSteps"); def_visible_primitive( set_tile_steps, "SetRykolTileSteps"); def_visible_primitive( get_tile_count, "GetRykolTileCount"); def_visible_primitive( get_patch_count, "GetRykolPatchCount"); def_visible_primitive( get_sel_edge, "GetRykolSelEdges"); def_visible_primitive( get_edge_vert1, "GetRykolEdgesVert1"); def_visible_primitive( get_edge_vert2, "GetRykolEdgesVert2"); def_visible_primitive( get_edge_vect1, "GetRykolEdgesVect1"); def_visible_primitive( get_edge_vect2, "GetRykolEdgesVect2"); def_visible_primitive( get_vertex_pos, "GetRykolVertexPos"); def_visible_primitive( set_vertex_pos, "SetRykolVertexPos"); def_visible_primitive( get_vector_pos, "GetRykolVectorPos"); def_visible_primitive( set_vector_pos, "SetRykolVectorPos"); def_visible_primitive( set_vector_count, "GetRykolVectorCount"); def_visible_primitive( set_vertex_count, "GetRykolVertexCount"); def_visible_primitive( set_interior_mode, "SetRykolInteriorMode"); def_visible_primitive( set_compute_interior, "RykolComputeInterior"); def_visible_primitive( set_tile_mode, "SetRykolTileMode"); def_visible_primitive( get_selected_vertex, "GetRykolSelVertex"); def_visible_primitive( get_selected_patch, "GetRykolSelPatch"); def_visible_primitive( get_selected_tile, "GetRykolSelTile"); def_visible_primitive( get_patch_vertex, "NeLGetPatchVertex"); def_visible_primitive( attach, "NeLAttachPatchMesh"); def_visible_primitive( weld, "NeLWeldPatchMesh"); def_visible_primitive( get_tile_tile_number, "NelGetTileTileNumber"); def_visible_primitive( get_tile_noise_number, "NelGetTileNoiseNumber"); def_visible_primitive( set_tile_noise_number, "NelSetTileNoiseNumber"); def_visible_primitive( load_bank, "NelLoadBank"); def_visible_primitive( get_tile_set, "NelGetTileSet"); def_visible_primitive( set_tile_bank, "NelSetTileBank"); def_visible_primitive( export_zone, "ExportRykolZone"); def_visible_primitive( import_zone, "NeLImportZone"); /* permettre l'acces à auto/manual intrior edges faire une methode pour interfacer la fonction compute interior edge donner un acces à tiledmode/patchmode (on/off) faire un getselectedvertex faire un getselectedpatch faire un getselectedtile */ /*def_visible_primitive( set_interior_mode, "SetRykolInteriorMode"); def_visible_primitive( set_vertex_count, "GetRykolVertexCount");*/ /*===========================================================================*\ | Implimentations of our new function calls | notice the appended '_cf' to show its the function implimentation \*===========================================================================*/ /*def_visible_primitive( get_sel_edge, "GetRykolSelEdges"); def_visible_primitive( get_edge_vertex, "GetRykolEdgesVertex"); def_visible_primitive( get_vertex_pos, "GetRykolVertexPos"); def_visible_primitive( set_vertex_pos, "SetRykolVertexPos"); def_visible_primitive( get_vector_pos, "GetRykolVectorPos"); def_visible_primitive( set_vector_pos, "SetRykolVectorPos");*/ void errorMessage (const char *msg, const char *title, Interface& it, bool dialog) { // Text or dialog ? if (dialog) { // Dialog message MessageBox (it.GetMAXHWnd(), msg, title, MB_OK|MB_ICONEXCLAMATION); } else { // Text message mprintf ((string(msg) + "\n").c_str()); } } Value* export_zone_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(export_zone, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "ExportRykolZone [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Boolean *ret=&false_value; // Is the flag dont export set ? if (CExportNel::getScriptAppData (node, NEL3D_APPDATA_DONTEXPORT, 0)) return ret; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nZone=arg_list[2]->to_int (); // Create a zone CZone zone; CZoneSymmetrisation zoneSymmetry; if (tri->rpatch->exportZone (node, &tri->patch, zone, zoneSymmetry, nZone, 160, 1, false)) { // Export path const char* sPath=arg_list[1]->to_string(); COFile file; if (file.open (sPath)) { zone.serial (file); ret=&true_value; } } } } return ret; } Value* import_zone_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count (export_zone, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' char *help = "NeLImportZone filename dialogError"; type_check (arg_list[0], String, help); type_check (arg_list[1], Boolean, help); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get the filename string filename = arg_list[0]->to_string(); // Get the flip bool dialog = arg_list[1]->to_bool ()!=FALSE; // Return value Value *ret = &undefined; // Load the zone CIFile input; if (input.open (filename)) { try { // The zone CZone zone; input.serial (zone); // Create an instance of NeL path mesh RPO* rpo = (RPO*) CreateInstance (GEOMOBJECT_CLASS_ID, RYKOLPATCHOBJ_CLASS_ID); rpo->rpatch = new RPatchMesh (); rpo->rpatch->rTess.TileTesselLevel = -5; // Convert the zone int zoneId; rpo->rpatch->importZone (&rpo->patch, zone, zoneId); // Create a derived object that references the rpo IDerivedObject *dobj = CreateDerivedObject(rpo); // Create a node in the scene that references the derived object INode *node = ip->CreateObjectNode (dobj); // Return the result ret = new MAXNode (node); // Redraw the viewports ip->RedrawViews(ip->GetTime()); } catch (Exception& e) { // Error message errorMessage (("Error when loading file "+filename+": "+e.what()).c_str(), "NeL import zone", *ip, dialog); } } else { // Error message errorMessage (("Can't open the file "+filename+" for reading.").c_str(), "NeL import zone", *ip, dialog); } return ret; } Value* get_selected_tile_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_selected_tile, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolSeltile [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Array *array=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nSize=tri->rpatch->tileSel.NumberSet(); array=new Array (nSize); int j=0; for (int i=0; irpatch->tileSel.GetSize(); i++) { if (tri->rpatch->tileSel[i]) array->append(Integer::intern(i+1)); } } } return array; } Value* get_selected_patch_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_selected_patch, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolSelPatch [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Array *array=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nSize=tri->patch.patchSel.NumberSet(); array=new Array (nSize); int j=0; for (int i=0; ipatch.patchSel.GetSize(); i++) { if (tri->patch.patchSel[i]) array->append(Integer::intern(i+1)); } } } return array; } Value* get_selected_vertex_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_selected_vertex, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolSelVertex [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Array *array=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nSize=tri->patch.vertSel.NumberSet(); array=new Array (nSize); int j=0; for (int i=0; ipatch.vertSel.GetSize(); i++) { if (tri->patch.vertSel[i]) array->append(Integer::intern(i+1)); } } } return array; } Value* set_tile_mode_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_interior_mode, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolTileMode [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id if (os.obj->CanConvertToType(Class_ID(PATCHOBJ_CLASS_ID, 0))) { bRet=true; RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { tri->rpatch->rTess.ModeTile=(arg_list[1]->to_int()!=0); } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* set_compute_interior_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_compute_interior, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "RykolComputeInterior [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id if (os.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID)) { bRet=true; RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) tri->patch.computeInteriors(); // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* set_interior_mode_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_interior_mode, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolInteriorMode [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id if (os.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID)) { bRet=true; RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { if (arg_list[1]->to_int()<=tri->patch.numPatches) tri->patch.patches[arg_list[1]->to_int()-1].SetAuto (arg_list[2]->to_int()); } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* set_vertex_count_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_vertex_count, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolVertexCount [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { nRet=tri->patch.numVerts; } } return Integer::intern(nRet); } Value* set_vector_count_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_vector_count, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolVectorCount [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { nRet=tri->patch.numVecs; } } return Integer::intern(nRet); } Value* set_vertex_pos_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_vertex_pos, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolVertexPos [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nVertex=arg_list[1]->to_int()-1; Point3 point=arg_list[2]->to_point3(); if ((nVertex>=0)&&(nVertexpatch.numVerts)) { bRet=true; tri->patch.verts[nVertex].p=point; tri->patch.InvalidateGeomCache(); tri->rpatch->InvalidateChannels(PART_ALL); node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } } return bRet?&true_value:&false_value; } Value* set_vector_pos_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_vector_pos, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolVectorPos [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nVertex=arg_list[1]->to_int()-1; Point3 point=arg_list[2]->to_point3(); if ((nVertex>=0)&&(nVertexpatch.numVecs)) { bRet=true; tri->patch.vecs[nVertex].p=point; tri->patch.InvalidateGeomCache(); tri->rpatch->InvalidateChannels(PART_ALL); node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } } return bRet?&true_value:&false_value; } Value* get_vertex_pos_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_vertex_pos, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolVertexPos [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Value *vRet=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nVertex=arg_list[1]->to_int()-1; if ((nVertex>=0)&&(nVertexpatch.numVerts)) { vRet=new Point3Value (tri->patch.verts[nVertex].p); } } } return vRet; } Value* get_vector_pos_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_vector_pos, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolVectorPos [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Value *vRet=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nVertex=arg_list[1]->to_int()-1; if ((nVertex>=0)&&(nVertexpatch.numVecs)) { vRet=new Point3Value (tri->patch.vecs[nVertex].p); } } } return vRet; } Value* get_edge_vect1_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_edge_vect1, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolEdgesVect1 [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nVert=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nEdge=arg_list[1]->to_int()-1; if ((nEdge>=0)&&(nEdgepatch.numEdges)) { nVert=tri->patch.edges[nEdge].vec12; } } } return Integer::intern(nVert); } Value* get_edge_vect2_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_edge_vect2, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolEdgesVect2 [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nVert=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nEdge=arg_list[1]->to_int()-1; if ((nEdge>=0)&&(nEdgepatch.numEdges)) { nVert=tri->patch.edges[nEdge].vec21; } } } return Integer::intern(nVert); } Value* get_edge_vert1_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_edge_vert1, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolEdgesVert1 [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nVert=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nEdge=arg_list[1]->to_int()-1; if ((nEdge>=0)&&(nEdgepatch.numEdges)) { nVert=tri->patch.edges[nEdge].v1; } } } return Integer::intern(nVert); } Value* get_edge_vert2_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_edge_vert2, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolEdgesVert2 [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nVert=-1; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nEdge=arg_list[1]->to_int()-1; if ((nEdge>=0)&&(nEdgepatch.numEdges)) { nVert=tri->patch.edges[nEdge].v2; } } } return Integer::intern(nVert); } Value* get_sel_edge_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_tile_steps, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolSelEdges [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? Array *array=NULL; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nSize=tri->patch.edgeSel.NumberSet(); array=new Array (nSize); int j=0; for (int i=0; ipatch.edgeSel.GetSize(); i++) { if (tri->patch.edgeSel[i]) array->append(Integer::intern(i+1)); //array->data[j++]=; } } } return array; } Value* set_steps_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_steps, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykolPatchSteps [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); if (classId==RYKOLPATCHOBJ_CLASS_ID) { bRet=true; static_cast(os.obj)->SetMeshSteps(arg_list[1]->to_int()); } if (os.obj->CanConvertToType(Class_ID(PATCHOBJ_CLASS_ID, 0))) { bRet=true; PatchObject *tri = (PatchObject *) os.obj->ConvertToType(ip->GetTime(), Class_ID(PATCHOBJ_CLASS_ID, 0)); if (tri) tri->SetMeshSteps(arg_list[1]->to_int()); // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } if (classId==Class_ID(PATCHOBJ_CLASS_ID,0)) { bRet=true; static_cast(os.obj)->SetMeshSteps(arg_list[1]->to_int()); } if (bRet) { // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* set_tile_steps_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(set_tile_steps, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "SetRykoltileSteps [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; if (os.obj) { // Get class id RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { bRet=true; int nTess=arg_list[1]->to_int(); if (nTess<-5) nTess=-5; if (nTess>5) nTess=5; tri->rpatch->rTess.TileTesselLevel=nTess; tri->rpatch->InvalidateChannels (PART_ALL); } if (bRet) { // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* get_tile_count_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_tile_count, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolTileCount [Zone] [PatchNumber]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { int nPatch=arg_list[1]->to_int(); if ((nPatch<(int)tri->rpatch->getUIPatchSize())&&(nPatch>=0)) { nRet=(1<<(tri->rpatch->getUIPatch (nPatch).NbTilesU))* (1<<(tri->rpatch->getUIPatch (nPatch).NbTilesV)); } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } if (nRet!=-1) { // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return Integer::intern(nRet); } Value* get_patch_vertex_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (3) check_arg_count(get_tile_count, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' char *message="NeLGetPatchVertex [NeLPatchMesh] [PatchId] [VertexId]"; type_check(arg_list[0], MAXNode, message); type_check(arg_list[1], Integer, message); type_check(arg_list[2], Integer, message); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // ok ? int nRet=-1; // Get the patch id int patchId = arg_list[1]->to_int() - 1; // Get the vertex id int vertId = arg_list[2]->to_int() - 1; // Valid vertex id ? if ((vertId>=0) && (vertId<4)) { // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { if ((patchId<(int)tri->patch.numPatches)&&(patchId>=0)) { // Get the vertex id nRet = tri->patch.patches[patchId].v[vertId] + 1; } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } if (nRet!=-1) { // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } } return Integer::intern(nRet); } Value* get_patch_count_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(get_patch_count, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "GetRykolPatchCount [Object]"); //type_check(arg_list[1], Integer, "SetRykolPatchSteps [Object]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { nRet=tri->rpatch->getUIPatchSize(); // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } if (nRet!=-1) { // redraw and update node->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return Integer::intern(nRet); } Value* get_tile_tile_number_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 4, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber] [Layer]"); type_check(arg_list[1], Integer, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber] [Layer]"); type_check(arg_list[2], Integer, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber] [Layer]"); type_check(arg_list[3], Integer, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber] [Layer]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; // Get the layer uint layer=arg_list[3]->to_int()-1; if (layer>=3) { mprintf ("Error: layer must be 1, 2, or 3\n"); } else { if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { // Get the patch number uint nPatch=arg_list[1]->to_int()-1; if (nPatch>=tri->rpatch->getUIPatchSize()) { mprintf ("Error: patch index is invalid.\n"); } else { // Number of tile in this patch uint nPatchCount=(1<<(tri->rpatch->getUIPatch (nPatch).NbTilesU))* (1<<(tri->rpatch->getUIPatch (nPatch).NbTilesV)); // Get the tile number uint tile=arg_list[2]->to_int()-1; if (tile>=nPatchCount) { mprintf ("Error: tile index is invalid.\n"); } else { // Tile index if (layer<(uint)tri->rpatch->getUIPatch (nPatch).getTileDesc (tile).getNumLayer()) { nRet=tri->rpatch->getUIPatch (nPatch).getTileDesc (tile).getLayer (layer).Tile+1; } else { nRet=0; } } } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } } } return Integer::intern(nRet); } Value* get_tile_noise_number_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 3, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber]"); type_check(arg_list[1], Integer, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber]"); type_check(arg_list[2], Integer, "NelGetTileTileNumber [Zone] [PatchNumber] [TileNumber]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? int nRet=-1; if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { // Get the patch number uint nPatch=arg_list[1]->to_int()-1; if (nPatch>=tri->rpatch->getUIPatchSize()) { mprintf ("Error: patch index is invalid.\n"); } else { // Number of tile in this patch uint nPatchCount=(1<<(tri->rpatch->getUIPatch (nPatch).NbTilesU))* (1<<(tri->rpatch->getUIPatch (nPatch).NbTilesV)); // Get the tile number uint tile=arg_list[2]->to_int()-1; if (tile>=nPatchCount) { mprintf ("Error: patch index is invalid.\n"); } else { // Tile index nRet=tri->rpatch->getUIPatch (nPatch).getTileDesc (tile).getDisplace ()+1; } } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } } return Integer::intern(nRet); } Value* set_tile_noise_number_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 4, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "NelGetTileNoiseNumber [Zone] [PatchNumber] [TileNumber] [noise]"); type_check(arg_list[1], Integer, "NelGetTileNoiseNumber [Zone] [PatchNumber] [TileNumber] [noise]"); type_check(arg_list[2], Integer, "NelGetTileNoiseNumber [Zone] [PatchNumber] [TileNumber] [noise]"); type_check(arg_list[3], Integer, "NelGetTileNoiseNumber [Zone] [PatchNumber] [TileNumber] [noise]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *node = arg_list[0]->to_node(); nlassert (node); // Get a Object pointer ObjectState os=node->EvalWorldState(ip->GetTime()); // ok ? bool bRet=false; // Get noise number uint noise=arg_list[3]->to_int()-1; if (noise>=16) { mprintf ("Error: noise value must be 1~16\n"); } else { if (os.obj) { // Get class id Class_ID classId=os.obj->ClassID(); RPO *tri = (RPO *) os.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (tri) { // Get the patch number uint nPatch=arg_list[1]->to_int()-1; if (nPatch>=tri->rpatch->getUIPatchSize()) { mprintf ("Error: patch index is invalid.\n"); } else { // Number of tile in this patch uint nPatchCount=(1<<(tri->rpatch->getUIPatch (nPatch).NbTilesU))* (1<<(tri->rpatch->getUIPatch (nPatch).NbTilesV)); // Get the tile number uint tile=arg_list[2]->to_int()-1; if (tile>=nPatchCount) { mprintf ("Error: patch index is invalid.\n"); } else { // Tile index tri->rpatch->getUIPatch (nPatch).getTileDesc (tile).setDisplace (noise); bRet=true; } } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (os.obj != tri) delete tri; } } } return bRet?&true_value:&false_value; } CTileBank scriptedBank; Value* load_bank_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 0, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' std::string bankName = GetBankPathName (); if (bankName!="") { try { // Open a file CIFile file; if (file.open (bankName)) { // Read the bank file.serial (scriptedBank); // Build xref scriptedBank.computeXRef (); // Ok return &true_value; } else { mprintf ("Error: can't open bank file %s\n", bankName.c_str()); } } catch (Exception& e) { // Error message mprintf ("Error: %s\n", e.what()); } } // Error return &false_value; } Value* get_tile_set_cf(Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], Integer, "NelGetTileSet [tileId]"); // ok ? int nRet=-1; // Get tile number uint tile=arg_list[0]->to_int()-1; if (tile>=(uint)scriptedBank.getTileCount()) { mprintf ("Error: tile number is wrong. (1 ~ %d)\n", scriptedBank.getTileCount()); } else { // Get the XRef for this bank int tileSet; int number; CTileBank::TTileType type; scriptedBank.getTileXRef (tile, tileSet, number, type); // Return value nRet=tileSet+1; } // Error return Integer::intern(nRet); } Value* set_tile_bank_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (4) check_arg_count(get_tile_count, 1, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], String, "NelSetTileBank [tile bank pathname]"); // ok ? const char *pathname = arg_list[0]->to_string(); // Get tile number SetBankPathName (pathname); // Error return &true_value; } //int attachReorient = 0; void DoAttach(INode *node, PatchMesh *patch, RPatchMesh *rpatch, INode *attNode, PatchMesh *attPatch, RPatchMesh *rattPatch, Interface *ip) { // Transform the shape for attachment: // If reorienting, just translate to align pivots // Otherwise, transform to match our transform Matrix3 attMat(1); if (0) { Matrix3 thisTM = node->GetNodeTM(ip->GetTime()); Matrix3 thisOTMBWSM = node->GetObjTMBeforeWSM(ip->GetTime()); Matrix3 thisPivTM = thisTM * Inverse(thisOTMBWSM); Matrix3 otherTM = attNode->GetNodeTM(ip->GetTime()); Matrix3 otherOTMBWSM = attNode->GetObjTMBeforeWSM(ip->GetTime()); Matrix3 otherPivTM = otherTM * Inverse(otherOTMBWSM); Point3 otherObjOffset = attNode->GetObjOffsetPos(); attMat = Inverse(otherPivTM) * thisPivTM; } else { attMat = attNode->GetObjectTM(ip->GetTime()) * Inverse(node->GetObjectTM(ip->GetTime())); } // RB 3-17-96 : Check for mirroring AffineParts parts; decomp_affine(attMat, &parts); if (parts.f < 0.0f) { int v[8], ct, ct2, j; Point3 p[9]; for (int i = 0; i < attPatch->numPatches; i++) { // Re-order rpatch if (attPatch->patches[i].type == PATCH_QUAD) { UI_PATCH rpatch=rattPatch->getUIPatch (i); int ctU=rpatch.NbTilesU<<1; int ctV=rpatch.NbTilesV<<1; int nU; for (nU=0; nUgetUIPatch (i).getTileDesc (nU+nV*ctU)=rpatch.getTileDesc (ctU-1-nU+(ctV-1-nV)*ctU); } } for (nU=0; nUgetUIPatch (i).setColor (nU+nV*(ctU+1), rpatch.getColor (ctU-nU+(ctV-nV)*ctU)); } } } // Re-order vertices ct = attPatch->patches[i].type == PATCH_QUAD ? 4 : 3; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].v[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].v[j] = v[ct - j - 1]; } // Re-order vecs ct = attPatch->patches[i].type == PATCH_QUAD ? 8 : 6; ct2 = attPatch->patches[i].type == PATCH_QUAD ? 5 : 3; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].vec[j]; } for (j = 0; j < ct; j++, ct2--) { if (ct2 < 0) ct2 = ct - 1; attPatch->patches[i].vec[j] = v[ct2]; } // Re-order enteriors if (attPatch->patches[i].type == PATCH_QUAD) { ct = 4; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].interior[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].interior[j] = v[ct - j - 1]; } } // Re-order aux if (attPatch->patches[i].type == PATCH_TRI) { ct = 9; for (j = 0; j < ct; j++) { p[j] = attPatch->patches[i].aux[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].aux[j] = p[ct - j - 1]; } } // Re-order TV faces if present for (int chan = 0; chan < patch->getNumMaps(); ++chan) { if (attPatch->tvPatches[chan]) { ct = 4; for (j = 0; j < ct; j++) { v[j] = attPatch->tvPatches[chan][i].tv[j]; } for (j = 0; j < ct; j++) { attPatch->tvPatches[chan][i].tv[j] = v[ct - j - 1]; } } } } } int i; for (i = 0; i < attPatch->numVerts; ++i) attPatch->verts[i].p = attPatch->verts[i].p * attMat; for (i = 0; i < attPatch->numVecs; ++i) attPatch->vecs[i].p = attPatch->vecs[i].p * attMat; attPatch->computeInteriors(); // theHold.Begin(); // Combine the materials of the two nodes. int mat2Offset = 0; Mtl *m1 = node->GetMtl(); Mtl *m2 = attNode->GetMtl(); bool condenseMe = FALSE; if (m1 && m2 &&(m1 != m2)) { //if (attachMat == ATTACHMAT_IDTOMAT) { int ct = 1; if (m1->IsMultiMtl()) ct = m1->NumSubMtls(); for (int i = 0; i < patch->numPatches; ++i) { int mtid = patch->getPatchMtlIndex(i); if (mtid >= ct) patch->setPatchMtlIndex(i, mtid % ct); } FitPatchIDsToMaterial(*attPatch, m2); /*if (condenseMat) condenseMe = TRUE;*/ } // the theHold calls here were a vain attempt to make this all undoable. // This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO. // theHold.Suspend(); /*if (attachMat == ATTACHMAT_MATTOID) { m1 = FitMaterialToPatchIDs(*patch, m1); m2 = FitMaterialToPatchIDs(*attPatch, m2); }*/ Mtl *multi = CombineMaterials(m1, m2, mat2Offset); /*if (attachMat == ATTACHMAT_NEITHER) mat2Offset = 0;*/ // theHold.Resume(); // We can't be in face subobject mode, else we screw up the materials: DWORD oldSL = patch->selLevel; DWORD roldSL = patch->selLevel; patch->selLevel = PATCH_OBJECT; rpatch->SetSelLevel (EP_OBJECT); node->SetMtl(multi); patch->selLevel = oldSL; rpatch->SetSelLevel (roldSL); m1 = multi; // canUndo = FALSE; // Absolutely cannot undo material combinations. } if (!m1 && m2) { // We can't be in face subobject mode, else we screw up the materials: DWORD oldSL = patch->selLevel; DWORD roldSL = rpatch->GetSelLevel(); patch->selLevel = PATCH_OBJECT; rpatch->SetSelLevel (EP_OBJECT); node->SetMtl(m2); patch->selLevel = oldSL; rpatch->SetSelLevel (roldSL); m1 = m2; } // Start a restore object... // if (theHold.Holding()) // theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoAttach")); // Do the attach patch->Attach(attPatch, mat2Offset); rpatch->Attach(rattPatch, *patch); // patchData->UpdateChanges(patch, rpatch); // patchData->TempData(this)->Invalidate(PART_TOPO | PART_GEOM); // Get rid of the original node ip->DeleteNode(attNode); // ResolveTopoChanges(); // theHold.Accept(GetString(IDS_TH_ATTACH)); if (m1 && condenseMe) { // Following clears undo stack. // patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); m1 = CondenseMatAssignments(*patch, m1); } } Value* attach_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(attach, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "NeLAttachPatchMesh [RykolPatchMeshSrc] [RykolPatchMeshDest]"); type_check(arg_list[1], MAXNode, "NeLAttachPatchMesh [RykolPatchMeshSrc] [RykolPatchMeshDest]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *nodeSrc = arg_list[0]->to_node(); INode *nodeDest = arg_list[1]->to_node(); nlassert (nodeSrc); nlassert (nodeDest); // Get a Object pointer ObjectState osSrc = nodeSrc->EvalWorldState (ip->GetTime()); ObjectState osDest = nodeDest->EvalWorldState (ip->GetTime()); // ok ? bool bRet=false; if (osSrc.obj && osDest.obj) { // Get class id if ( (osSrc.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID)) && (osDest.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))) { RPO *triSrc = (RPO *) osSrc.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); RPO *triDest = (RPO *) osDest.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (triSrc && triDest) { DoAttach (nodeDest, &triDest->patch, triDest->rpatch, nodeSrc, &triSrc->patch, triSrc->rpatch, ip); bRet=true; } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (osSrc.obj != triSrc) delete triSrc; // redraw and update triDest->patch.InvalidateGeomCache(); triDest->rpatch->InvalidateChannels(PART_ALL); nodeDest->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } Value* weld_cf (Value** arg_list, int count) { // Make sure we have the correct number of arguments (2) check_arg_count(attach, 2, count); // Check to see if the arguments match up to what we expect // We want to use 'TurnAllTexturesOn ' type_check(arg_list[0], MAXNode, "NeLWeldPatchMesh [RykolPatchMeshSrc] [threshold]"); type_check(arg_list[1], Float, "NeLWeldPatchMesh [RykolPatchMeshSrc] [threshold]"); // Get a good interface pointer Interface *ip = MAXScript_interface; // Get a INode pointer from the argument passed to us INode *nodeSrc = arg_list[0]->to_node(); float threshold = arg_list[1]->to_float(); nlassert (nodeSrc); // Get a Object pointer ObjectState osSrc = nodeSrc->EvalWorldState (ip->GetTime()); // ok ? bool bRet=false; if (osSrc.obj) { // Get class id if (osSrc.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID)) { RPO *triSrc = (RPO *) osSrc.obj->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID); if (triSrc) { triSrc->patch.vertSel.SetAll (); triSrc->patch.Weld (threshold, TRUE); triSrc->rpatch->Weld (&triSrc->patch); bRet=true; } // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (osSrc.obj != triSrc) delete triSrc; // redraw and update triSrc->patch.InvalidateGeomCache(); triSrc->rpatch->InvalidateChannels(PART_ALL); nodeSrc->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } } return bRet?&true_value:&false_value; } /*===========================================================================*\ | MAXScript Plugin Initialization \*===========================================================================*/ __declspec( dllexport ) void LibInit() { }