jack3
August 25, 2022, 9:32pm
1
I want to scale a mesh before drawing it, how do I scale it by a specified number?
What should be defined before this code?
The Scale method can only take one argument, what if I want to take more than one?
mesh.scale(width);
mesh.scale(length);
mesh.scale(depth);
doc.Objects.AddMesh(mesh);
I would like to 3D scale around the origin.
I can only get one return value, what should I do if I want to get more than one?
jack3
August 26, 2022, 1:31pm
2
width,length,depth
These are all double values.
Willem
(Willem Derks)
August 26, 2022, 1:36pm
3
Hi
Apply a transform with
GeometryBase.Transform Method
creating a transform with
Does that help?
jack3
August 26, 2022, 1:37pm
4
Hi Willem
I also referred to that Method, but I will try again.
jack3
August 26, 2022, 3:20pm
5
This code would fill the entire screen.
It will not be the number that is set by default.
Plane plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
Transform scale3d = new Transform();
scale3d = Transform.Scale(plane, length, width, depth);
meshAll_2.Transform(scale3d);
doc.Objects.AddMesh(meshAll_2);
Hi @jack3 , note that the 3 values used in Transform.Scale
are scale factors not real dimensional units. To scale to a specific dimension you would need to measure the current dimension eg. using the bounding box and then compute the desired scale factors yourself in order to use them.
_
c.
jack3
August 26, 2022, 5:37pm
7
Hi @clement
Thanks for the advice.
If you don’t mind, do you have any examples?
Hi @jack3 , sure, to test below, create a box, in the world xy plane:
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
def DoSomething():
obj_id = rs.GetObject("Select the box", rs.filter.polysurface, True, False)
if not obj_id: return
rh_obj = rs.coercerhinoobject(obj_id, True, True)
plane = Rhino.Geometry.Plane.WorldXY
bbox = rh_obj.Geometry.GetBoundingBox(plane)
length, width, height = 24, 12, 18
x_factor = length / bbox.Min.DistanceTo(bbox.PointAt(1,0,0))
y_factor = width / bbox.Min.DistanceTo(bbox.PointAt(0,1,0))
z_factor = height / bbox.Min.DistanceTo(bbox.PointAt(0,0,1))
xform = Rhino.Geometry.Transform.Scale(plane, x_factor, y_factor, z_factor)
rh_obj.Geometry.Transform(xform)
rh_obj.CommitChanges()
scriptcontext.doc.Views.Redraw()
DoSomething()
_
c.
jack3
August 26, 2022, 6:14pm
9
Hi @clement
Thank you for providing us with a sample.
But I am building in C#…
Hi @jack3 ,
sorry i am using python only. You should be able to transfer above into C# if you understand the concept, i’ll try:
Plane plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
BoundingBox bbox = meshAll_2.GetBoundingBox(plane);
double x_factor = length / bbox.Min.DistanceTo(bbox.PointAt(1,0,0));
double y_factor = width / bbox.Min.DistanceTo(bbox.PointAt(0,1,0));
double z_factor = height / bbox.Min.DistanceTo(bbox.PointAt(0,0,1));
Transform scale3d = new Transform();
scale3d = Transform.Scale(plane, x_factor, y_factor, z_factor);
meshAll_2.Transform(scale3d);
doc.Objects.AddMesh(meshAll_2);
...
above asumes that you have length
, width
and height
somewhere in your code.
_
c.
jack3
August 26, 2022, 6:42pm
11
Hi @clement
It is an adequate sample.
Thank you very much.
jack3
August 26, 2022, 8:12pm
12
private void ComputeMesh()
Is there a wrong way to define Scale in this Method?
internal class DisplayTestConduit : DisplayConduit
{
private readonly Mesh m_mesh = null;
private Mesh m_mesh0 = null;
private readonly Color m_color = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor;
public double Length
{
get => m_length;
set
{
if (value > 0.001)
{
m_length = value;
ComputeMesh();
}
}
}
private double m_length = 10.38;
public double Width
{
get => m_width;
set
{
if (value > 0.001)
{
m_width = value;
ComputeMesh();
}
}
}
private double m_width = 5.19;
public double Depth
{
get => m_depth;
set
{
if (value > 0.001)
{
m_depth = value;
ComputeMesh();
}
}
}
private double m_depth = 3.17;
private void ComputeMesh()
{
m_mesh0 = m_mesh.DuplicateMesh();
m_mesh0.Scale(Length);
m_mesh0.Scale(Width);
m_mesh0.Scale(Depth);
}
Hi @jack3 ,
according to your initial question i would say yes. According to the documentation for GeometryBase.Scale the number you put for scaleFactor
is not a distance but a uniform factor, it works for all 3 dimensions (x,y,z). So if you would like to scale some geometry to double its size you would use:
m_mesh0.Scale(2.0)
and to scale it to half it’s size you would use
m_mesh0.Scale(0.5)
looking at your recent code you would scale all 3 axes 3 times with different values. I am not sure this is desired. Are you trying to scale your geometry to a specific size ?
_
c.
jack3
August 26, 2022, 9:08pm
14
Hi @clement
I am trying to output a number specified by double.
jack3
August 26, 2022, 9:10pm
15
I define it this way in RunCommad.
var conduit = new DisplayTestConduit(meshAll_2)
{
Length = length,
Width = width,
Depth = depth,
Enabled = true
};
doc.Views.Redraw();
jack3
August 26, 2022, 10:25pm
16
It seems that the Scale Method is not used to scale each of Length, Width, and Depth by 1D, but what should I do if I want to scale each item by 1D?
Hi @jack3 , to scale only in one direction, set all other factors to 1.0. For example below scales only the height by a factor of 2.0:
scale1d = Transform.Scale(plane, 1.0, 1.0, 2.0);
meshAll_2.Transform(scale1d);
_
c.
jack3
August 27, 2022, 10:30am
18
How can I define the ComputeMesh() Method so that the Length, Width, and Depth are each 1DScale in the ComputeMesh() Method?
Hi @jack3 , Transform.Scale
method creates a non uniform scaling transform along 3 axes. To get all 3 at once you would use something close to this:
private void ComputeMesh()
{
m_mesh0 = m_mesh.DuplicateMesh();
Plane plane = Plane.WorldXY;
Transform xform = new Transform();
xform = Transform.Scale(plane, length, width, depth);
m_mesh0.Transform(xform);
}
If you want a mesh for each singular axis, you would create 3 transforms and set the scale factors to 1.0 where you do not want a scaling to happen. See my previous reply in case you want to scale only in one direction.
_
c.
1 Like