Jump to content
3DCoat Forums

Core API scripts


wendallhitherd
 Share

Recommended Posts

  • Member

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 by wendallhitherd
Link to comment
Share on other sites

  • Member
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 by wendallhitherd
  • Like 1
Link to comment
Share on other sites

  • Member

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 :D 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 by wendallhitherd
Link to comment
Share on other sites

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.
Link to comment
Share on other sites

  • 4 weeks later...
  • Member

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 by wendallhitherd
Link to comment
Share on other sites

  • 2 weeks later...
  • Member
Carlosan
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 :D 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 by wendallhitherd
  • Thanks 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...