I see the repository but I can’t navigate all the files and folders.
Where exactly are the functions located?
The bindings are here: rhino3dm/src/bindings at main · mcneel/rhino3dm · GitHub
oh, I see, so if a new function is added here it will appear in the Python, JS and .net api?
When all the right things have been done, yes. That is the idea.
Why must everything be hard…
PowerShell 7.4.1
PS E:\> cd appdev/git/rhino3dm/src
PS E:\AppDev\GIT\rhino3dm\src> dir
Directory: E:\AppDev\GIT\rhino3dm\src
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 20-Mar-24 18:13 bindings
d---- 20-Mar-24 18:15 build
d---- 20-Mar-24 18:13 docgen
d---- 20-Mar-24 18:13 dotnet
d---- 20-Mar-24 18:13 js
d---- 20-Mar-24 18:13 lib
d---- 20-Mar-24 18:13 librhino3dm_native
d---- 20-Mar-24 18:13 methodgen
d---- 20-Mar-24 18:13 rhino3dm
-a--- 20-Mar-24 18:13 2696 build_dotnet.py
-a--- 20-Mar-24 18:13 911 build_javascript.py
-a--- 20-Mar-24 18:13 4590 CMakeLists.txt
-a--- 20-Mar-24 18:13 1690 create_python_vcxproj.py
-a--- 20-Mar-24 18:13 31194 ios.toolchain.cmake
-a--- 20-Mar-24 18:13 5 version.txt
PS E:\AppDev\GIT\rhino3dm\src> python create_python_vcxproj.py
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19045.
-- The C compiler identification is MSVC 19.37.32825.0
-- The CXX compiler identification is MSVC 19.37.32825.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Python Compile
CMake Error at CMakeLists.txt:18 (add_subdirectory):
The source directory
E:/AppDev/GIT/rhino3dm/src/lib/pybind11
does not contain a CMakeLists.txt file.
NODE=
CMake Error at CMakeLists.txt:33 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_gl.cpp
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_gl.skip
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:34 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp932.cpp
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp932.skip
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:35 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp949.cpp
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp949.skip
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:37 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_gl.skip
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_gl.cpp
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:38 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp932.skip
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp932.cpp
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:39 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp949.skip
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/opennurbs_unicode_cp949.cpp
because: The system cannot find the file specified.
CMake Error at CMakeLists.txt:41 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/android_uuid/gen_uuid_nt.c
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/android_uuid/gen_uuid_nt.skip
because: The system cannot find the path specified.
CMake Error at CMakeLists.txt:43 (file):
file RENAME failed to rename
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/android_uuid/gen_uuid_nt.skip
to
E:/AppDev/GIT/rhino3dm/src/lib/opennurbs/android_uuid/gen_uuid_nt.c
because: The system cannot find the path specified.
CMake Error at CMakeLists.txt:105 (pybind11_add_module):
Unknown CMake command "pybind11_add_module".
-- Configuring incomplete, errors occurred!
Traceback (most recent call last):
File "E:\AppDev\GIT\rhino3dm\src\create_python_vcxproj.py", line 43, in <module>
createproject()
File "E:\AppDev\GIT\rhino3dm\src\create_python_vcxproj.py", line 30, in createproject
for line in fileinput.input("_rhino3dm.vcxproj", inplace=1):
File "C:\Python311\Lib\fileinput.py", line 251, in __next__
line = self._readline()
^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\fileinput.py", line 337, in _readline
os.rename(self._filename, self._backupfilename)
FileNotFoundError: [WinError 2] The system cannot find the file specified: '_rhino3dm.vcxproj' -> '_rhino3dm.vcxproj.bak'
PS E:\AppDev\GIT\rhino3dm\src>
Or, you could just ask it to do it for you…
– Dale
I wanted to challenge myself and take some burden from you, especially since I don’t know if others need/want it as I do.
It just makes more sense to me that you can create Nurbs Curves and Surfaces like so:
def NurbsCurve(degree:int, knots_count:int, knot_vector:list, multiplicity:list, control_points_count:int, control_points:list, weights_list:list, is_rational:bool, continuity:int):
# etc...
return nurbs_curve_object
respectively,
def NurbsSurface(degree_u:int, degree_v:int, knots_count_u:int, knots_count_v:int, knot_vector_u:list, knot_vector_v:list, multiplicity_u:list, multiplicity_v:list, control_points_count:int, control_points:list, weights_list:list, is_rational:bool):
# etc...
return nurbs_surface_object
You don’t have all of the source. This repository has git submodules that need to be retrieved.
git submodule update —init
Thanks.
Do I run this inside the rhino3dm folder or one folder above?
Or in the future when you clone a repository use: git clone --recursive https://github.com/mcneel/rhino3dm
. That will also handle all submodules.
ok I’ll try this now, seems easier
PS E:\AppDev\GIT\rhino3dm\src> python .\create_python_vcxproj.py
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19045.
-- The C compiler identification is MSVC 19.37.32825.0
-- The CXX compiler identification is MSVC 19.37.32825.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Python Compile
-- pybind11 v2.12.0 dev1
CMake Warning (dev) at lib/pybind11/tools/FindPythonLibsNew.cmake:98 (find_package):
Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
are removed. Run "cmake --help-policy CMP0148" for policy details. Use
the cmake_policy command to set the policy and suppress this warning.
Call Stack (most recent call first):
lib/pybind11/tools/pybind11Tools.cmake:50 (find_package)
lib/pybind11/tools/pybind11Common.cmake:188 (include)
lib/pybind11/CMakeLists.txt:211 (include)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Found PythonInterp: C:/Python311/python.exe (found suitable version "3.11.3", minimum required is "3.6")
-- Found PythonLibs: C:/Python311/libs/python311.lib
-- Performing Test HAS_MSVC_GL_LTCG
-- Performing Test HAS_MSVC_GL_LTCG - Success
NODE=
CMake Warning (dev) at lib/draco/CMakeLists.txt:37 (include):
Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
are removed. Run "cmake --help-policy CMP0148" for policy details. Use
the cmake_policy command to set the policy and suppress this warning.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Found PythonInterp: C:/Python311/python.exe (found version "3.11.3")
-- Configuring done (10.3s)
-- Generating done (1.2s)
-- Build files have been written to: E:/AppDev/GIT/rhino3dm/src/build/py311_64bit
PS E:\AppDev\GIT\rhino3dm\src>
Looks promising
So…
if my function is like this:
BND_NurbsCurve* CreateFromDegreeKnotsPoints(int degree, int nr_knots, int nr_points, std::vector<double> knot_vector, std::vector<int> multiplicities, std::vector<double> control_points, std::vector<double> weights, bool is_rational)
{
if ((degree >= nr_points) && (degree < 1))
{
return nullptr;
}
if (knot_vector.size() != multiplicities.size())
{
return nullptr;
}
if (control_points.size() / 3 != nr_points)
{
return nullptr;
}
if (weights.size() != nr_points)
{
return nullptr;
}
// hardcoding dimension to 3
int dim = 3;
int order = degree + 1;
// constructing the point list from array(vector) of doubles
std::vector<ON_3dPoint> cv_list;
for (int i = 0; i < nr_points; i++)
{
ON_3dPoint pt = ON_3dPoint(control_points.at(i), control_points.at(i + 1), control_points.at(i + 2));
cv_list.push_back(pt);
i = i + 3;
}
ON_NurbsCurve* crv = new ON_NurbsCurve(dim, is_rational, order, nr_points);
for (int i = 0; i < nr_points; i++)
{
crv->SetCV(i, cv_list.at(i));
}
// constructing the knot vector from knots + multiplicities (TO BE DECIDED: removing first and last knot or not?)
int kn_idx = 0;
for (int k = 0; k < knot_vector.size(); k++)
{
for (int m = 0; m < multiplicities.size(); m++)
{
int multiplicity = multiplicities.at(m);
int knot = knot_vector.at(k);
if (multiplicity == 1)
{
crv->SetKnot(kn_idx, knot);
kn_idx = kn_idx + 1;
}
else if (multiplicity > 1)
{
for (int mi = 0; mi < multiplicity; mi++)
{
crv->SetKnot(kn_idx, knot);
kn_idx = kn_idx + 1;
}
}
}
}
return new BND_NurbsCurve(crv, nullptr);
}
How would it be added to the python bindings?
Mainly, what I wonder is: will python know how to convert python list to std::vector to call the function?
build succeeded in DEBUG but in RELEASE I got this error:
36>LINK : fatal error LNK1181: cannot open input file 'draco_static\Release\draco.lib'
36>Done building project "_rhino3dm.vcxproj" -- FAILED.
37>------ Build started: Project: ALL_BUILD, Configuration: Release x64 ------
37>Building Custom Rule E:/AppDev/GIT/rhino3dm/src/CMakeLists.txt
38>------ Skipped Build: Project: INSTALL, Configuration: Release x64 ------
38>Project not selected to build for this solution configuration
========== Build: 36 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========
========== Build started at 22:38 and took 06:52.699 minutes ==========
Could anyone please explain how can I test the debug build?
I got these files in the DEBUG folder:
To get a Python module to test use python3 setup.py build
. The setup.py
is in the root of the repository. This will create a build
folder in which is a folder with name that tells you for what python version and operating system. On my M2 it looks like this:
╭─jesterking ∞ at jesterM2 in ~/dev/li/rhino3dm/build/lib.macosx-10.9-universal2-cpython-310 on main✘✘✘ 24-03-21 - 9:04:42
╰─⠠⠵ ls on main|✚2
rhino3dm
This rhino3dm
folder you see is the Python module. When you cd
into that folder containing rhino3dm
you can run Python and import rhino3dm
. Use print(rhino3dm)
to verify you loaded the freshly built one. After that you can write any code you need to test.
Copy rhino3dm
to a place where you have your other code that relies on this and run your script to see your additions worked.
Thanks,
What I did yesterday was I used the .pyd file generated with VisualStudio compiling the project.
However, for some reason my new function wasn’t there when I tried print(dir(rhino3dm.NurbsCurve))
I assume something in here:
I did not do correctly, or there is also another place where I need to add my new function.
update:
This is my entry:
.def_static("CreateFromDegreeKnotsPoints", &BND_NurbsCurve::CreateFromDegreeKnotsPoints, py::arg("degree"), py::arg("nr_knots"), py::arg("nr_points"), py::arg("knot_vector"), py::arg("multiplicities"), py::arg("control_points"), py::arg("weights"), py::arg("is_rational")) //(int degree, int nr_knots, int nr_points, std::vector<double> knot_vector, std::vector<int> multiplicities, std::vector<double> control_points, std::vector<double> weights, bool is_rational)
I’ve no idea if that’s ok, I don’t know if std::vector type is properly converted. The build succeeds.
You indeed need to add the .def_static
entry. std::vector
should work. You can check elsewhere in the code how this is done, for instance in the PointCloud bindings.
Of course you can also look at the BND_NurbsCurve::Create2
implementation and see how an enumerable object is used there.
do I have to put my function with “2” in here?
#if defined(ON_PYTHON_COMPILE)
#endif
Yes, if you add only for Python.
Add it after the def_static
for CreateFromEllipse
.
Order could matter, but in this case it doesn’t. It looked like the most reasonable place naming-wise.