Member wendallhitherd Posted June 10, 2022 Member Report Share Posted June 10, 2022 (edited) I have made a box for putting commands in! This iterates over the entire root subtree and sets it to surface and then back to voxel again int main(){ { // get the sculpt root auto r = coat::Scene::sculptRoot(); auto active = coat::Scene::current(); coat::ui::toRoom("Sculpt"); // iterate through all sculpt objects r.iterateSubtree ( [&](coat::SceneElement el) -> bool { if (el.isSculptObject()) { coat::Volume vol = el.Volume(); vol.toSurface(); int cur_polycount = vol.getPolycount(); vol.toVoxels(); } return false; } ); } return 0; } now to proceed with my dumb questions: - How would I test for if the scene element is "selected" using quick pick +? - coat::mat4 is referenced in the docs as being identical to cMat4. In practice they seem to do different things, cMat4 raises errors when run in 3DC despite being "fine" according to the linter, and coat::mat4 m = coat::mat4:Identity gets picked up as an error in the linter but runs fine in 3DC. (I'm using the default settings from the VS install 3DC triggers automatically) - What if I wanted to apply transforms on everything and resample volumes in global space? I can seem to set transforms and transform voxlayers in the core api but I don't see a way to apply transform to the layer. I suppose this is where calling more UI comes in? Edited June 10, 2022 by wendallhitherd Quote Link to comment Share on other sites More sharing options...
Member wendallhitherd Posted June 10, 2022 Author Member Report Share Posted June 10, 2022 (edited) EXPORT int main() { { // get the sculpt root auto root = coat::Scene::sculptRoot(); auto active = coat::Scene::current(); //coat::ui::toRoom("Sculpt"); // iterate through all sculpt objects active.iterateSubtree ( [&](coat::SceneElement el) -> bool { if (el.isSculptObject()) { coat::Volume vol = el.Volume(); vol.toSurface(); int cur_polycount = vol.getPolycount(); //vol.toVoxels(); el.selectOne(); coat::ui::cmd("$Resample", [cur_polycount] { //coat::ui::setEditBoxValue("$ResampleParams::RequiredPolycount", tgt_polycount); float scale = 0.5f; coat::ui::setSliderValue("$ResampleParams::ResamplingScale", scale); coat::ui::cmd("$DialogButton#1"); //coat::ui::apply(); } ); } return false; } ); } return 0; } This will reduce the polycount of the subtree of the currently active object by half. it leverages both core api scene commands as well as sending commands to the 3DC UI to "click buttons". Super excited about the potential for automating 3DC here!! Edited June 10, 2022 by wendallhitherd 1 Quote Link to comment Share on other sites More sharing options...
Member wendallhitherd Posted June 11, 2022 Author Member Report Share Posted June 11, 2022 (edited) I almost finished a script that would make all layers in a subtree a consistent polygon density, but this is giving janky results, I think it's because GetVolume is not doing what I think it is (size x * size y * size z)... In any case once it works it will be super handy to be able to get rid of wildly different topo densities in a subtree without having to vox merge but it looks like the BBX / BBY of a sculpt layer is tucked away in the VoxelObject, which can only be retrieved by a pointer, and I have no idea how to use pointers. Here's the WIP script anyway. Also one thing I'm noticing, there seems to be no way in the API to check if an object is selected or not, or iterate over selected objects :B I found "active" but I think that's a setter and not a getter EXPORT int main() { { // get the sculpt root //auto root = coat::Scene::sculptRoot(); auto active = coat::Scene::current(); float polys_per_unit_size; float resample_scale = 1.0f; coat::Volume vol; if (active.isSculptObject()) { coat::Volume active_vol = active.Volume(); polys_per_unit_size = (float)active_vol.getPolycount() / active_vol.getVolume(); } else { return false; } //coat::ui::toRoom("Sculpt"); // iterate through all sculpt objects active.iterateSubtree ( [&](coat::SceneElement el) -> bool { if (el.isSculptObject()) { el.selectOne(); vol = el.Volume(); vol.toVoxels(); coat::ui::cmd("$ToGlobalSpace"); coat::ui::cmd("$ToUniformSpace"); int target_polys = (int)(polys_per_unit_size * vol.getSquare()); float resample_scale = (float)target_polys / (float)vol.getVolume(); coat::ui::cmd("$Resample", [resample_scale, target_polys] { coat::ui::setSliderValue("$ResampleParams::ResamplingScale", resample_scale); //coat::ui::setEditBoxValue("$ResampleParams::RequiredPolycount", target_polys); coat::ui::cmd("$DialogButton#1"); } ); } return false; } ); } return 0; } Edited June 11, 2022 by wendallhitherd Quote Link to comment Share on other sites More sharing options...
Andrew Shpagin Posted June 11, 2022 Report Share Posted June 11, 2022 You may use comms::cMat4 (and similar where you see typdefs) for the correct compiling. Or use using namespace comms; But on my side, I am getting correct hints with linter with coat::mat4 as well. Interesting why are you not getting this... If you are using the debugger, drop the 3dcoat.natvis into the project folder and debug watch will be friendly for all internal coat data types. Quote Link to comment Share on other sites More sharing options...
Andrew Shpagin Posted June 11, 2022 Report Share Posted June 11, 2022 For consistency use square rather than volume to equalize density. And remember that if you increase amount of polygons 4X then the polygon size decreases 2X. Quote Link to comment Share on other sites More sharing options...
Member wendallhitherd Posted July 4, 2022 Author Member Report Share Posted July 4, 2022 (edited) I am feeling very dumb... Played around with the script a bunch to try and get it to work, played with the math on paper, seems out polycount = in_polycount * scaleFactor^2 but this thing gives wrong results, and gets wrongerer with each iteration. Makes me feel like a value in the loop is not being reset properly? #include <CoreAPI.h> EXPORT int main() { { auto active = coat::Scene::current(); float base_square_size; float base_polycount; float cur_square_size; float cur_polys; float scale_factor; float target_polys; float resample_scale = 1.0f; coat::Volume vol; if (active.isSculptObject()) { coat::Volume active_vol = active.Volume(); base_square_size = active_vol.getSquare(); base_polycount = (float)active_vol.getPolycount(); } else { return false; } active.iterateSubtree( [&](coat::SceneElement el) -> bool { if (el.isSculptObject()) { el.selectOne(); vol = el.Volume(); vol.toSurface(); coat::ui::cmd("$ToGlobalSpace"); coat::ui::cmd("$ToUniformSpace"); cur_square_size = vol.getSquare(); cur_polys = (float)vol.getPolycount(); scale_factor = sqrt(cur_square_size / base_square_size); target_polys = pow(scale_factor, 2) * base_polycount; resample_scale = (target_polys / cur_polys); coat::ui::cmd("$Resample", [resample_scale, target_polys] { coat::ui::setSliderValue("$ResampleParams::ResamplingScale", resample_scale); coat::ui::setEditBoxValue("$ResampleParams::RequiredPolycount", target_polys); coat::ui::cmd("$DialogButton#1"); } ); } return false; } ); } return 0; } Edited July 4, 2022 by wendallhitherd Quote Link to comment Share on other sites More sharing options...
Member wendallhitherd Posted July 17, 2022 Author Member Report Share Posted July 17, 2022 (edited) This post was recognized by Carlosan! wendallhitherd was awarded the badge 'Great Content' and 1 points. Here is some core api scripts I have been using: if you have feedback please upgrade my scripts I don't know C++ thatdecimate_subtree_half.cpp well, the syntax seems quite arcane compared to python (so many []%~*'s)ReduceSubtreePolycountHalf.cpp First decimates the subtree by half after converting to surface mode, the second simply resamples to half. Thinking about making a git repo for these scripts? Edited July 17, 2022 by wendallhitherd 1 Quote Link to comment Share on other sites More sharing options...
Member wendallhitherd Posted July 17, 2022 Author Member Report Share Posted July 17, 2022 and here are the 3dcpacks decimate_subtree_half.3dcpack ReduceSubtreePolycountHalf.3dcpack 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.