This is page 2 of 8. Use http://codebase.md/jingcheng-chen/rhinomcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .github
│ └── workflows
│ ├── mcp-server-publish.yml
│ └── rhino-plugin-publish.yml
├── .gitignore
├── assets
│ ├── claude_enable_instruction.jpg
│ ├── cursor_enable_instruction.jpg
│ ├── cursor_usage_instruction.jpg
│ ├── demo1.jpg
│ ├── demo2.jpg
│ ├── rhino_plugin_instruction.jpg
│ └── rhinomcp_logo.svg
├── demo_chats
│ ├── create_6x6x6_boxes.txt
│ └── create_rhinoceros_lego_blocks.txt
├── LICENSE
├── README.md
├── rhino_mcp_plugin
│ ├── .gitignore
│ ├── Commands
│ │ ├── MCPStartCommand.cs
│ │ ├── MCPStopCommand.cs
│ │ └── MCPVersionCommand.cs
│ ├── EmbeddedResources
│ │ └── plugin-utility.ico
│ ├── Functions
│ │ ├── _utils.cs
│ │ ├── CreateLayer.cs
│ │ ├── CreateObject.cs
│ │ ├── CreateObjects.cs
│ │ ├── DeleteLayer.cs
│ │ ├── DeleteObject.cs
│ │ ├── ExecuteRhinoscript.cs
│ │ ├── GetDocumentInfo.cs
│ │ ├── GetObjectInfo.cs
│ │ ├── GetOrSetCurrentLayer.cs
│ │ ├── GetSelectedObjectsInfo.cs
│ │ ├── ModifyObject.cs
│ │ ├── ModifyObjects.cs
│ │ └── SelectObjects.cs
│ ├── manifest.yml
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── launchSettings.json
│ ├── rhinomcp.csproj
│ ├── rhinomcp.sln
│ ├── RhinoMCPPlugin.cs
│ ├── RhinoMCPServer.cs
│ ├── RhinoMCPServerController.cs
│ └── Serializers
│ └── Serializer.cs
└── rhino_mcp_server
├── .gitignore
├── dev.sh
├── main.py
├── pyproject.toml
├── README.md
├── src
│ └── rhinomcp
│ ├── __init__.py
│ ├── prompts
│ │ └── assert_general_strategy.py
│ ├── server.py
│ ├── static
│ │ └── rhinoscriptsyntax.py
│ └── tools
│ ├── create_layer.py
│ ├── create_object.py
│ ├── create_objects.py
│ ├── delete_layer.py
│ ├── delete_object.py
│ ├── execute_rhinoscript_python_code.py
│ ├── get_document_info.py
│ ├── get_object_info.py
│ ├── get_or_set_current_layer.py
│ ├── get_rhinoscript_python_code_guide.py
│ ├── get_rhinoscript_python_function_names.py
│ ├── get_selected_objects_info.py
│ ├── modify_object.py
│ ├── modify_objects.py
│ └── select_objects.py
├── static
│ ├── application.py
│ ├── block.py
│ ├── compat.py
│ ├── curve.py
│ ├── dimension.py
│ ├── document.py
│ ├── geometry.py
│ ├── grips.py
│ ├── group.py
│ ├── hatch.py
│ ├── layer.py
│ ├── light.py
│ ├── line.py
│ ├── linetype.py
│ ├── material.py
│ ├── mesh.py
│ ├── object.py
│ ├── plane.py
│ ├── pointvector.py
│ ├── selection.py
│ ├── surface.py
│ ├── toolbar.py
│ ├── transformation.py
│ ├── userdata.py
│ ├── userinterface.py
│ ├── utility.py
│ └── view.py
└── uv.lock
```
# Files
--------------------------------------------------------------------------------
/rhino_mcp_plugin/RhinoMCPServer.cs:
--------------------------------------------------------------------------------
```csharp
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Text;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using Rhino;
10 | using Rhino.Commands;
11 | using Rhino.Geometry;
12 | using Rhino.Input;
13 | using Rhino.Input.Custom;
14 | using Rhino.UI;
15 | using Newtonsoft.Json;
16 | using Newtonsoft.Json.Linq;
17 | using static System.Runtime.InteropServices.JavaScript.JSType;
18 | using System.Text.Json;
19 | using Rhino.DocObjects;
20 | using rhinomcp.Serializers;
21 | using JsonException = Newtonsoft.Json.JsonException;
22 | using Eto.Forms;
23 | using RhinoMCPPlugin.Functions;
24 |
25 | namespace RhinoMCPPlugin
26 | {
27 | public class RhinoMCPServer
28 | {
29 | private string host;
30 | private int port;
31 | private bool running;
32 | private TcpListener listener;
33 | private Thread serverThread;
34 | private readonly object lockObject = new object();
35 | private RhinoMCPFunctions handler;
36 |
37 | public RhinoMCPServer(string host = "127.0.0.1", int port = 1999)
38 | {
39 | this.host = host;
40 | this.port = port;
41 | this.running = false;
42 | this.listener = null;
43 | this.serverThread = null;
44 | this.handler = new RhinoMCPFunctions();
45 | }
46 |
47 |
48 | public void Start()
49 | {
50 | lock (lockObject)
51 | {
52 | if (running)
53 | {
54 | RhinoApp.WriteLine("Server is already running");
55 | return;
56 | }
57 |
58 | running = true;
59 | }
60 |
61 | try
62 | {
63 | // Create TCP listener
64 | IPAddress ipAddress = IPAddress.Parse(host);
65 | listener = new TcpListener(ipAddress, port);
66 | listener.Start();
67 |
68 | // Start server thread
69 | serverThread = new Thread(ServerLoop);
70 | serverThread.IsBackground = true;
71 | serverThread.Start();
72 |
73 | RhinoApp.WriteLine($"RhinoMCP server started on {host}:{port}");
74 | }
75 | catch (Exception e)
76 | {
77 | RhinoApp.WriteLine($"Failed to start server: {e.Message}");
78 | Stop();
79 | }
80 | }
81 |
82 | public void Stop()
83 | {
84 | lock (lockObject)
85 | {
86 | running = false;
87 | }
88 |
89 | // Close listener
90 | if (listener != null)
91 | {
92 | try
93 | {
94 | listener.Stop();
95 | }
96 | catch
97 | {
98 | // Ignore errors on closing
99 | }
100 | listener = null;
101 | }
102 |
103 | // Wait for thread to finish
104 | if (serverThread != null && serverThread.IsAlive)
105 | {
106 | try
107 | {
108 | serverThread.Join(1000); // Wait up to 1 second
109 | }
110 | catch
111 | {
112 | // Ignore errors on join
113 | }
114 | serverThread = null;
115 | }
116 |
117 | RhinoApp.WriteLine("RhinoMCP server stopped");
118 | }
119 |
120 | private void ServerLoop()
121 | {
122 | RhinoApp.WriteLine("Server thread started");
123 |
124 | while (IsRunning())
125 | {
126 | try
127 | {
128 | // Set a timeout to check running condition periodically
129 | listener.Server.ReceiveTimeout = 1000;
130 | listener.Server.SendTimeout = 1000;
131 |
132 | // Wait for client connection
133 | if (listener.Pending())
134 | {
135 | TcpClient client = listener.AcceptTcpClient();
136 | RhinoApp.WriteLine($"Connected to client: {client.Client.RemoteEndPoint}");
137 |
138 | // Handle client in a separate thread
139 | Thread clientThread = new Thread(() => HandleClient(client));
140 | clientThread.IsBackground = true;
141 | clientThread.Start();
142 | }
143 | else
144 | {
145 | // No pending connections, sleep a bit to prevent CPU overuse
146 | Thread.Sleep(100);
147 | }
148 | }
149 | catch (Exception e)
150 | {
151 | RhinoApp.WriteLine($"Error in server loop: {e.Message}");
152 |
153 | if (!IsRunning())
154 | break;
155 |
156 | Thread.Sleep(500);
157 | }
158 | }
159 |
160 | RhinoApp.WriteLine("Server thread stopped");
161 | }
162 |
163 | private bool IsRunning()
164 | {
165 | lock (lockObject)
166 | {
167 | return running;
168 | }
169 | }
170 |
171 | private void HandleClient(TcpClient client)
172 | {
173 | RhinoApp.WriteLine("Client handler started");
174 |
175 | byte[] buffer = new byte[8192];
176 | string incompleteData = string.Empty;
177 |
178 | try
179 | {
180 | NetworkStream stream = client.GetStream();
181 |
182 | while (IsRunning())
183 | {
184 | try
185 | {
186 | // Check if there's data available to read
187 | if (client.Available > 0 || stream.DataAvailable)
188 | {
189 | int bytesRead = stream.Read(buffer, 0, buffer.Length);
190 | if (bytesRead == 0)
191 | {
192 | RhinoApp.WriteLine("Client disconnected");
193 | break;
194 | }
195 |
196 | string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
197 | incompleteData += data;
198 |
199 | try
200 | {
201 | // Try to parse as JSON
202 | JObject command = JObject.Parse(incompleteData);
203 | incompleteData = string.Empty;
204 |
205 | // Execute command on Rhino's main thread
206 | RhinoApp.InvokeOnUiThread(new Action(() =>
207 | {
208 | try
209 | {
210 | JObject response = ExecuteCommand(command);
211 | string responseJson = JsonConvert.SerializeObject(response);
212 |
213 | try
214 | {
215 | byte[] responseBytes = Encoding.UTF8.GetBytes(responseJson);
216 | stream.Write(responseBytes, 0, responseBytes.Length);
217 | }
218 | catch
219 | {
220 | RhinoApp.WriteLine("Failed to send response - client disconnected");
221 | }
222 | }
223 | catch (Exception e)
224 | {
225 | RhinoApp.WriteLine($"Error executing command: {e.Message}");
226 | try
227 | {
228 | JObject errorResponse = new JObject
229 | {
230 | ["status"] = "error",
231 | ["message"] = e.Message
232 | };
233 |
234 | byte[] errorBytes = Encoding.UTF8.GetBytes(errorResponse.ToString());
235 | stream.Write(errorBytes, 0, errorBytes.Length);
236 | }
237 | catch
238 | {
239 | // Ignore send errors
240 | }
241 | }
242 | }));
243 | }
244 | catch (JsonException)
245 | {
246 | // Incomplete JSON data, wait for more
247 | }
248 | }
249 | else
250 | {
251 | // No data available, sleep a bit to prevent CPU overuse
252 | Thread.Sleep(50);
253 | }
254 | }
255 | catch (Exception e)
256 | {
257 | RhinoApp.WriteLine($"Error receiving data: {e.Message}");
258 | break;
259 | }
260 | }
261 | }
262 | catch (Exception e)
263 | {
264 | RhinoApp.WriteLine($"Error in client handler: {e.Message}");
265 | }
266 | finally
267 | {
268 | try
269 | {
270 | client.Close();
271 | }
272 | catch
273 | {
274 | // Ignore errors on close
275 | }
276 | RhinoApp.WriteLine("Client handler stopped");
277 | }
278 | }
279 |
280 | private JObject ExecuteCommand(JObject command)
281 | {
282 | try
283 | {
284 | string cmdType = command["type"]?.ToString();
285 | JObject parameters = command["params"] as JObject ?? new JObject();
286 |
287 | RhinoApp.WriteLine($"Executing command: {cmdType}");
288 |
289 | JObject result = ExecuteCommandInternal(cmdType, parameters);
290 |
291 | RhinoApp.WriteLine("Command execution complete");
292 | return result;
293 | }
294 | catch (Exception e)
295 | {
296 | RhinoApp.WriteLine($"Error executing command: {e.Message}");
297 | return new JObject
298 | {
299 | ["status"] = "error",
300 | ["message"] = e.Message
301 | };
302 | }
303 | }
304 |
305 | private JObject ExecuteCommandInternal(string cmdType, JObject parameters)
306 | {
307 |
308 | // Dictionary to map command types to handler methods
309 | Dictionary<string, Func<JObject, JObject>> handlers = new Dictionary<string, Func<JObject, JObject>>
310 | {
311 | ["get_document_info"] = this.handler.GetDocumentInfo,
312 | ["create_object"] = this.handler.CreateObject,
313 | ["create_objects"] = this.handler.CreateObjects,
314 | ["get_object_info"] = this.handler.GetObjectInfo,
315 | ["get_selected_objects_info"] = this.handler.GetSelectedObjectsInfo,
316 | ["delete_object"] = this.handler.DeleteObject,
317 | ["modify_object"] = this.handler.ModifyObject,
318 | ["modify_objects"] = this.handler.ModifyObjects,
319 | ["execute_rhinoscript_python_code"] = this.handler.ExecuteRhinoscript,
320 | ["select_objects"] = this.handler.SelectObjects,
321 | ["create_layer"] = this.handler.CreateLayer,
322 | ["get_or_set_current_layer"] = this.handler.GetOrSetCurrentLayer,
323 | ["delete_layer"] = this.handler.DeleteLayer
324 | // Add more handlers as needed
325 | };
326 |
327 | if (handlers.TryGetValue(cmdType, out var handler))
328 | {
329 | var doc = RhinoDoc.ActiveDoc;
330 | var record = doc.BeginUndoRecord("Run MCP command");
331 | try
332 | {
333 | JObject result = handler(parameters);
334 | return new JObject
335 | {
336 | ["status"] = "success",
337 | ["result"] = result
338 | };
339 | }
340 | catch (Exception e)
341 | {
342 | RhinoApp.WriteLine($"Error in handler: {e.Message}");
343 | return new JObject
344 | {
345 | ["status"] = "error",
346 | ["message"] = e.Message
347 | };
348 | }
349 | finally
350 | {
351 | doc.EndUndoRecord(record);
352 | }
353 | }
354 | else
355 | {
356 | return new JObject
357 | {
358 | ["status"] = "error",
359 | ["message"] = $"Unknown command type: {cmdType}"
360 | };
361 | }
362 | }
363 | }
364 | }
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/group.py:
--------------------------------------------------------------------------------
```python
1 | import scriptcontext
2 |
3 | from rhinoscript import utility as rhutil
4 |
5 |
6 | def AddGroup(group_name=None):
7 | """Adds a new empty group to the document
8 | Parameters:
9 | group_name (str, optional): name of the new group. If omitted, rhino automatically
10 | generates the group name
11 | Returns:
12 | str: name of the new group if successful
13 | None: is not successful or on error
14 | Example:
15 | import rhinoscriptsyntax as rs
16 | name = rs.AddGroup("NewGroup")
17 | See Also:
18 | DeleteGroup
19 | GroupCount
20 | GroupNames
21 | IsGroup
22 | RenameGroup
23 | """
24 | index = -1
25 | if group_name is None:
26 | index = scriptcontext.doc.Groups.Add()
27 | else:
28 | if not isinstance(group_name, str): group_name = str(group_name)
29 | index = scriptcontext.doc.Groups.Add( group_name )
30 | rc = scriptcontext.doc.Groups.GroupName(index)
31 | if rc is None: return scriptcontext.errorhandler()
32 | return rc
33 |
34 |
35 | def AddObjectsToGroup(object_ids, group_name):
36 | """Adds one or more objects to an existing group.
37 | Parameters:
38 | object_ids ([guid, ...]) list of Strings or Guids representing the object identifiers
39 | group_name (str): the name of an existing group
40 | Returns:
41 | number: number of objects added to the group
42 | Example:
43 | import rhinoscriptsyntax as rs
44 | name = "NewGroup"
45 | object_ids = rs.GetObjects("Select objects to add to group")
46 | if object_ids: rs.AddObjectsToGroup(object_ids, name)
47 | See Also:
48 | AddObjectToGroup
49 | IsGroupEmpty
50 | ObjectGroups
51 | ObjectsByGroup
52 | """
53 | if not isinstance(group_name, str): group_name = str(group_name)
54 | index = scriptcontext.doc.Groups.Find(group_name)
55 | object_ids = rhutil.coerceguidlist(object_ids)
56 | if index<0 or not object_ids: return 0
57 | if not scriptcontext.doc.Groups.AddToGroup(index, object_ids): return 0
58 | return len(object_ids)
59 |
60 |
61 | def AddObjectToGroup(object_id, group_name):
62 | """Adds a single object to an existing group.
63 | Parameters:
64 | object_id (guid): String or Guid representing the object identifier
65 | group_name (str): the name of an existing group
66 | Returns:
67 | True or False representing success or failure
68 | Example:
69 | import rhinoscriptsyntax as rs
70 | name = "NewGroup"
71 | id = rs.GetObject("Select object to add to group")
72 | if id: rs.AddObjectToGroup(id,name)
73 | See Also:
74 | AddObjectsToGroup
75 | IsGroupEmpty
76 | ObjectGroups
77 | ObjectsByGroup
78 | """
79 | object_id = rhutil.coerceguid(object_id)
80 | if not isinstance(group_name, str): group_name = str(group_name)
81 | index = scriptcontext.doc.Groups.Find(group_name)
82 | if object_id is None or index<0: return False
83 | return scriptcontext.doc.Groups.AddToGroup(index, object_id)
84 |
85 |
86 | def DeleteGroup(group_name):
87 | """Removes an existing group from the document. Reference groups cannot be
88 | removed. Deleting a group does not delete the member objects
89 | Parameters:
90 | group_name (str): the name of an existing group
91 | Returns:
92 | bool: True or False representing success or failure
93 | Example:
94 | import rhinoscriptsyntax as rs
95 | groups = rs.GroupNames()
96 | if groups:
97 | for group in groups: rs.DeleteGroup(group)
98 | See Also:
99 | AddGroup
100 | GroupCount
101 | GroupNames
102 | IsGroup
103 | RenameGroup
104 | """
105 | if not isinstance(group_name, str): group_name = str(group_name)
106 | index = scriptcontext.doc.Groups.Find(group_name)
107 | return scriptcontext.doc.Groups.Delete(index)
108 |
109 |
110 | def GroupCount():
111 | """Returns the number of groups in the document
112 | Returns:
113 | number: the number of groups in the document
114 | Example:
115 | import rhinoscriptsyntax as rs
116 | numgroups = rs.GroupCount()
117 | print("Group count:{}".format(numgroups))
118 | See Also:
119 | AddGroup
120 | DeleteGroup
121 | GroupNames
122 | IsGroup
123 | RenameGroup
124 | """
125 | return scriptcontext.doc.Groups.Count
126 |
127 |
128 | def GroupNames():
129 | """Returns the names of all the groups in the document
130 | None if no names exist in the document
131 | Returns:
132 | list(str, ...): the names of all the groups in the document. None if no names exist in the document
133 | Example:
134 | import rhinoscriptsyntax as rs
135 | groups = rs.GroupNames()
136 | if groups:
137 | for group in groups: print(group)
138 | See Also:
139 | AddGroup
140 | DeleteGroup
141 | GroupCount
142 | IsGroup
143 | RenameGroup
144 | """
145 | names = scriptcontext.doc.Groups.GroupNames(True)
146 | if names is None: return None
147 | return list(names)
148 |
149 |
150 | def HideGroup(group_name):
151 | """Hides a group of objects. Hidden objects are not visible, cannot be
152 | snapped to, and cannot be selected
153 | Parameters:
154 | group_name (str): the name of an existing group
155 | Returns:
156 | number: The number of objects that were hidden
157 | Example:
158 | import rhinoscriptsyntax as rs
159 | groups = rs.GroupNames()
160 | if groups:
161 | for group in groups: rs.HideGroup(group)
162 | See Also:
163 | LockGroup
164 | ShowGroup
165 | UnlockGroup
166 | """
167 | index = scriptcontext.doc.Groups.Find(group_name)
168 | if index<0: return 0
169 | return scriptcontext.doc.Groups.Hide(index);
170 |
171 |
172 | def IsGroup(group_name):
173 | """Verifies the existance of a group
174 | Parameters:
175 | group_name (str): the name of the group to check for
176 | Returns:
177 | bool: True or False
178 | Example:
179 | import rhinoscriptsyntax as rs
180 | group = rs.GetString("Group name to verify")
181 | if rs.IsGroup(group):
182 | print("The group exists.")
183 | else:
184 | print("The group does not exist.")
185 | See Also:
186 | AddGroup
187 | DeleteGroup
188 | GroupCount
189 | GroupNames
190 | RenameGroup
191 | """
192 | if not isinstance(group_name, str): group_name = str(group_name)
193 | return scriptcontext.doc.Groups.Find(group_name)>=0
194 |
195 |
196 | def IsGroupEmpty(group_name):
197 | """Verifies that an existing group is empty, or contains no object members
198 | Parameters:
199 | group_name (str): the name of an existing group
200 | Returns:
201 | bool: True or False if group_name exists
202 | None: if group_name does not exist
203 | Example:
204 | import rhinoscriptsyntax as rs
205 | names = rs.GroupNames()
206 | if names:
207 | for name in names:
208 | if rs.IsGroupEmpty(name): rs.DeleteGroup(name)
209 | See Also:
210 | AddObjectsToGroup
211 | AddObjectToGroup
212 | RemoveObjectFromAllGroups
213 | RemoveObjectFromGroup
214 | RemoveObjectsFromGroup
215 | """
216 | if not isinstance(group_name, str): group_name = str(group_name)
217 | index = scriptcontext.doc.Groups.Find(group_name)
218 | if index<0: return scriptcontext.errorhandler()
219 | return scriptcontext.doc.Groups.GroupObjectCount(index)>0
220 |
221 |
222 | def LockGroup(group_name):
223 | """Locks a group of objects. Locked objects are visible and they can be
224 | snapped to. But, they cannot be selected
225 | Parameters:
226 | group_name (str): the name of an existing group
227 | Returns:
228 | number: Number of objects that were locked if successful
229 | None: on error
230 | Example:
231 | import rhinoscriptsyntax as rs
232 | names = rs.GroupNames()
233 | if names:
234 | for name in names: rs.LockGroup(name)
235 | See Also:
236 | HideGroup
237 | ShowGroup
238 | UnlockGroup
239 | """
240 | if not isinstance(group_name, str): group_name = str(group_name)
241 | index = scriptcontext.doc.Groups.Find(group_name)
242 | if index<0: return scriptcontext.errorhandler()
243 | return scriptcontext.doc.Groups.Lock(index);
244 |
245 |
246 | def RemoveObjectFromAllGroups(object_id):
247 | """Removes a single object from any and all groups that it is a member.
248 | Neither the object nor the group can be reference objects
249 | Parameters:
250 | object_id (guid): the object identifier
251 | Returns:
252 | bool: True or False indicating success or failure
253 | Example:
254 | import rhinoscriptsyntax as rs
255 | object = rs.GetObject("Select object")
256 | if object: rs.RemoveObjectFromAllGroups(object)
257 | See Also:
258 | IsGroupEmpty
259 | ObjectGroups
260 | ObjectsByGroup
261 | RemoveObjectFromGroup
262 | RemoveObjectsFromGroup
263 | """
264 | rhinoobject = rhutil.coercerhinoobject(object_id, True, True)
265 | if rhinoobject.GroupCount<1: return False
266 | attrs = rhinoobject.Attributes
267 | attrs.RemoveFromAllGroups()
268 | return scriptcontext.doc.Objects.ModifyAttributes(rhinoobject, attrs, True)
269 |
270 |
271 | def RemoveObjectFromGroup(object_id, group_name):
272 | """Remove a single object from an existing group
273 | Parameters:
274 | object_id (guid): the object identifier
275 | group_name (str): the name of an existing group
276 | Returns:
277 | bool: True or False indicating success or failure
278 | Example:
279 | import rhinoscriptsyntax as rs
280 | name = "NewGroup"
281 | id = rs.GetObject("Select object")
282 | if name: rs.RemoveObjectFromGroup(id,name)
283 | See Also:
284 | IsGroupEmpty
285 | ObjectGroups
286 | ObjectsByGroup
287 | RemoveObjectFromAllGroups
288 | RemoveObjectsFromGroup
289 | """
290 | count = RemoveObjectsFromGroup(object_id, group_name)
291 | return not (count is None or count<1)
292 |
293 |
294 | def RemoveObjectsFromGroup(object_ids, group_name):
295 | """Removes one or more objects from an existing group
296 | Parameters:
297 | object_ids ([guid, ...]): a list of object identifiers
298 | group_name (str): the name of an existing group
299 | Returns:
300 | number: The number of objects removed from the group is successful
301 | None: on error
302 | Example:
303 | import rhinoscriptsyntax as rs
304 | group = "NewGroup"
305 | ids = rs.GetObjects("Select objects")
306 | if ids: rs.RemoveObjectsFromGroup(ids,group)
307 | See Also:
308 | IsGroupEmpty
309 | ObjectGroups
310 | ObjectsByGroup
311 | RemoveObjectFromAllGroups
312 | RemoveObjectFromGroup
313 | """
314 | if not isinstance(group_name, str): group_name = str(group_name)
315 | index = scriptcontext.doc.Groups.Find(group_name)
316 | if index<0: return scriptcontext.errorhandler()
317 | id = rhutil.coerceguid(object_ids, False)
318 | if id: object_ids = [id]
319 | objects_removed = 0
320 | for id in object_ids:
321 | rhinoobject = rhutil.coercerhinoobject(id, True, True)
322 | attrs = rhinoobject.Attributes
323 | attrs.RemoveFromGroup(index)
324 | if scriptcontext.doc.Objects.ModifyAttributes(rhinoobject, attrs, True):
325 | objects_removed+=1
326 | return objects_removed
327 |
328 |
329 | def RenameGroup(old_name, new_name):
330 | """Renames an existing group
331 | Parameters:
332 | old_name (str): the name of an existing group
333 | new_name (str): the new group name
334 | Returns:
335 | str: the new group name if successful
336 | None: on error
337 | Example:
338 | import rhinoscriptsyntax as rs
339 | strOldGroup = rs.GetString("Old group name")
340 | if strOldGroup:
341 | strNewGroup = rs.GetString("New group name")
342 | if strNewName: rs.RenameGroup(strOldGroup, strNewGroup)
343 | See Also:
344 | AddGroup
345 | DeleteGroup
346 | GroupCount
347 | GroupNames
348 | IsGroup
349 | """
350 | if not isinstance(old_name, str): old_name = str(old_name)
351 | index = scriptcontext.doc.Groups.Find(old_name)
352 | if index<0: return scriptcontext.errorhandler()
353 | if not isinstance(new_name, str): new_name = str(new_name)
354 | if scriptcontext.doc.Groups.ChangeGroupName(index, new_name):
355 | return new_name
356 | return scriptcontext.errorhandler()
357 |
358 |
359 | def ShowGroup(group_name):
360 | """Shows a group of previously hidden objects. Hidden objects are not
361 | visible, cannot be snapped to, and cannot be selected
362 | Parameters:
363 | group_name (str): the name of an existing group
364 | Returns:
365 | number: The number of objects that were shown if successful
366 | None: on error
367 | Example:
368 | import rhinoscriptsyntax as rs
369 | groups = rs.GroupNames()
370 | if groups:
371 | for group in groups: rs.ShowGroup(group)
372 | See Also:
373 | HideGroup
374 | LockGroup
375 | UnlockGroup
376 | """
377 | if not isinstance(group_name, str): group_name = str(group_name)
378 | index = scriptcontext.doc.Groups.Find(group_name)
379 | if index<0: return scriptcontext.errorhandler()
380 | return scriptcontext.doc.Groups.Show(index);
381 |
382 |
383 | def UnlockGroup(group_name):
384 | """Unlocks a group of previously locked objects. Lockes objects are visible,
385 | can be snapped to, but cannot be selected
386 | Parameters:
387 | group_name (str): the name of an existing group
388 | Returns:
389 | number: The number of objects that were unlocked if successful
390 | None: on error
391 | Example:
392 | import rhinoscriptsyntax as rs
393 | groups = rs.GroupNames()
394 | if groups:
395 | for group in groups: rs.UnlockGroup(group)
396 | See Also:
397 | HideGroup
398 | LockGroup
399 | ShowGroup
400 | """
401 | if not isinstance(group_name, str): group_name = str(group_name)
402 | index = scriptcontext.doc.Groups.Find(group_name)
403 | if index<0: return scriptcontext.errorhandler()
404 | return scriptcontext.doc.Groups.Unlock(index);
405 |
406 |
407 | def ObjectTopGroup(object_id):
408 | """Returns the top most group name that an object is assigned. This function primarily applies to objects that are members of nested groups
409 | Parameters:
410 | object_id (guid): String or Guid representing the object identifier
411 | Returns:
412 | str: the top group's name if successful
413 | None: if not successful
414 | Example:
415 | import rhinoscriptsyntax as rs
416 | id = rs.GetObject("Select object to add to group")
417 | groupName = rs.ObjectTopGroup(id)
418 | See Also:
419 | ObjectGroups
420 | """
421 | object_id = rhutil.coerceguid(object_id)
422 | if object_id is None: return None
423 | obj = scriptcontext.doc.Objects.FindId(object_id)
424 | topGroupName = None
425 | groupIndexes = obj.GetGroupList()
426 | if groupIndexes is not None:
427 | topGroupIndex = max(groupIndexes) # this is a bad assumption. See RH-49189
428 | topGroupName = scriptcontext.doc.Groups.FindIndex(topGroupIndex).Name
429 | return topGroupName
430 |
431 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/grips.py:
--------------------------------------------------------------------------------
```python
1 | import Rhino
2 |
3 | import scriptcontext
4 |
5 | import rhinocompat as compat
6 | from rhinoscript import utility as rhutil
7 |
8 |
9 | def __neighborgrip(i, object_id, index, direction, enable):
10 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
11 | grips = rhobj.GetGrips()
12 | if not grips or len(grips)<=index: return scriptcontext.errorhandler()
13 | grip = grips[index]
14 | next_grip=None
15 | if direction==0:
16 | next_grip = grip.NeighborGrip(i,0,0,False)
17 | else:
18 | next_grip = grip.NeighborGrip(0,i,0,False)
19 | if next_grip and enable:
20 | next_grip.Select(True)
21 | scriptcontext.doc.Views.Redraw()
22 | return next_grip
23 |
24 |
25 | def EnableObjectGrips(object_id, enable=True):
26 | """Enables or disables an object's grips. For curves and surfaces, these are
27 | also called control points.
28 | Parameters:
29 | object_id (guid): identifier of the object
30 | enable (bool, optional): if True, the specified object's grips will be turned on.
31 | Otherwise, they will be turned off
32 | Returns:
33 | bool: True on success, False on failure
34 | Example:
35 | import rhinoscriptsyntax as rs
36 | objects = rs.GetObjects("Select objects")
37 | if objects: [rs.EnableObjectGrips(obj) for obj in objs]
38 | See Also:
39 | ObjectGripCount
40 | ObjectGripsOn
41 | ObjectGripsSelected
42 | SelectObjectGrips
43 | UnselectObjectGrips
44 | """
45 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
46 | if enable!=rhobj.GripsOn:
47 | rhobj.GripsOn = enable
48 | scriptcontext.doc.Views.Redraw()
49 |
50 |
51 | def GetObjectGrip(message=None, preselect=False, select=False):
52 | """Prompts the user to pick a single object grip
53 | Parameters:
54 | message (str, optional): prompt for picking
55 | preselect (bool, optional): allow for selection of pre-selected object grip.
56 | select (bool, optional): select the picked object grip.
57 | Returns:
58 | tuple(guid, number, point): defining a grip record.
59 | [0] = identifier of the object that owns the grip
60 | [1] = index value of the grip
61 | [2] = location of the grip
62 | None: on error
63 | Example:
64 | import rhinoscriptsyntax as rs
65 | curve = rs.GetObject("Select a curve", rs.filter.curve)
66 | if curve:
67 | rs.EnableObjectGrips( curve )
68 | grip = rs.GetObjectGrip("Select a curve grip")
69 | if grip: print(grip[2])
70 | See Also:
71 | GetObjectGrips
72 | """
73 | if not preselect:
74 | scriptcontext.doc.Objects.UnselectAll()
75 | scriptcontext.doc.Views.Redraw()
76 | rc, grip = Rhino.Input.RhinoGet.GetGrip(message)
77 | if rc!=Rhino.Commands.Result.Success: return scriptcontext.errorhandler()
78 | if select:
79 | grip.Select(True, True)
80 | scriptcontext.doc.Views.Redraw()
81 | return grip.OwnerId, grip.Index, grip.CurrentLocation
82 |
83 |
84 | def GetObjectGrips(message=None, preselect=False, select=False):
85 | """Prompts user to pick one or more object grips from one or more objects.
86 | Parameters:
87 | message (str, optional): prompt for picking
88 | preselect (bool, optional): allow for selection of pre-selected object grips
89 | select (bool, optional) select the picked object grips
90 | Returns:
91 | list((guid, number, point), ...): containing one or more grip records. Each grip record is a tuple
92 | [n][0] = identifier of the object that owns the grip
93 | [n][1] = index value of the grip
94 | [n][2] = location of the grip
95 | None: on error
96 | Example:
97 | import rhinoscriptsyntax as rs
98 | curves = rs.GetObjects("Select curves", rs.filter.curves)
99 | if curves:
100 | for curve in curves: rs.EnableObjectGrips(curve)
101 | grips = rs.GetObjectGrips("Select curve grips")
102 | if grips: for grip in grips: print(grip[0])
103 | See Also:
104 | GetObjectGrip
105 | """
106 | if not preselect:
107 | scriptcontext.doc.Objects.UnselectAll()
108 | scriptcontext.doc.Views.Redraw()
109 | getrc, grips = Rhino.Input.RhinoGet.GetGrips(message)
110 | if getrc!=Rhino.Commands.Result.Success or not grips:
111 | return scriptcontext.errorhandler()
112 | rc = []
113 | for grip in grips:
114 | id = grip.OwnerId
115 | index = grip.Index
116 | location = grip.CurrentLocation
117 | rc.append((id, index, location))
118 | if select: grip.Select(True, True)
119 | if select: scriptcontext.doc.Views.Redraw()
120 | return rc
121 |
122 |
123 | def NextObjectGrip(object_id, index, direction=0, enable=True):
124 | """Returns the next grip index from a specified grip index of an object
125 | Parameters:
126 | object_id (guid): identifier of the object
127 | index (number): zero based grip index from which to get the next grip index
128 | direction ([number, number], optional): direction to get the next grip index (0=U, 1=V)
129 | enable (bool, optional): if True, the next grip index found will be selected
130 | Returns:
131 | number: index of the next grip on success
132 | None: on failure
133 | Example:
134 | import rhinoscriptsyntax as rs
135 | object_id = rs.GetObject("Select curve", rs.filter.curve)
136 | if object_id:
137 | rs.EnableObjectGrips( object_id )
138 | count = rs.ObjectGripCount( object_id )
139 | for i in range(0,count,2):
140 | rs.NextObjectGrip(object_id, i, 0, True)
141 | See Also:
142 | EnableObjectGrips
143 | PrevObjectGrip
144 | """
145 | return __neighborgrip(1, object_id, index, direction, enable)
146 |
147 |
148 | def ObjectGripCount(object_id):
149 | """Returns number of grips owned by an object
150 | Parameters:
151 | object_id (guid): identifier of the object
152 | Returns:
153 | number: number of grips if successful
154 | None: on error
155 | Example:
156 | import rhinoscriptsyntax as rs
157 | obj = rs.GetObject("Select object")
158 | if rs.ObjectGripsOn(obj):
159 | print("Grip count ={}".format(rs.ObjectGripCount(obj)))
160 | See Also:
161 | EnableObjectGrips
162 | ObjectGripsOn
163 | ObjectGripsSelected
164 | SelectObjectGrips
165 | UnselectObjectGrips
166 | """
167 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
168 | grips = rhobj.GetGrips()
169 | if not grips: return scriptcontext.errorhandler()
170 | return grips.Length
171 |
172 |
173 | def ObjectGripLocation(object_id, index, point=None):
174 | """Returns or modifies the location of an object's grip
175 | Parameters:
176 | object_id (guid) identifier of the object
177 | index (number): index of the grip to either query or modify
178 | point (point, optional): 3D point defining new location of the grip
179 | Returns:
180 | point: if point is not specified, the current location of the grip referenced by index
181 | point: if point is specified, the previous location of the grip referenced by index
182 | None: on error
183 | Example:
184 | import rhinoscriptsyntax as rs
185 | obj = rs.GetObject("Select curve", rs.filter.curve)
186 | if obj:
187 | rs.EnableObjectGrips(obj)
188 | point = rs.ObjectGripLocation(obj, 0)
189 | point[0] = point[0] + 1.0
190 | point[1] = point[1] + 1.0
191 | point[2] = point[2] + 1.0
192 | rs.ObjectGripLocation(obj, 0, point)
193 | rs.EnableObjectGrips(obj, False)
194 | See Also:
195 | EnableObjectGrips
196 | ObjectGripLocations
197 | """
198 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
199 | if not rhobj.GripsOn: return scriptcontext.errorhandler()
200 | grips = rhobj.GetGrips()
201 | if not grips or index<0 or index>=grips.Length:
202 | return scriptcontext.errorhandler()
203 | grip = grips[index]
204 | rc = grip.CurrentLocation
205 | if point:
206 | grip.CurrentLocation = rhutil.coerce3dpoint(point, True)
207 | scriptcontext.doc.Objects.GripUpdate(rhobj, True)
208 | scriptcontext.doc.Views.Redraw()
209 | return rc
210 |
211 |
212 | def ObjectGripLocations(object_id, points=None):
213 | """Returns or modifies the location of all grips owned by an object. The
214 | locations of the grips are returned in a list of Point3d with each position
215 | in the list corresponding to that grip's index. To modify the locations of
216 | the grips, you must provide a list of points that contain the same number
217 | of points at grips
218 | Parameters:
219 | object_id (guid): identifier of the object
220 | points ([point, ...], optional) list of 3D points identifying the new grip locations
221 | Returns:
222 | list(point, ...): if points is not specified, the current location of all grips
223 | list(point, ...): if points is specified, the previous location of all grips
224 | None: if not successful
225 | Example:
226 | import rhinoscriptsyntax as rs
227 | obj = rs.GetObject("Select curve", rs.filter.curve)
228 | if obj:
229 | rs.EnableObjectGrips( obj )
230 | points = rs.ObjectGripLocations(obj)
231 | for point in points: print(point)
232 | See Also:
233 | EnableObjectGrips
234 | ObjectGripCount
235 | ObjectGripLocation
236 | """
237 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
238 | if not rhobj.GripsOn: return scriptcontext.errorhandler()
239 | grips = rhobj.GetGrips()
240 | if grips is None: return scriptcontext.errorhandler()
241 | rc = [grip.CurrentLocation for grip in grips]
242 | if points and len(points)==len(grips):
243 | points = rhutil.coerce3dpointlist(points, True)
244 | for i, grip in enumerate(grips):
245 | point = points[i]
246 | grip.CurrentLocation = point
247 | scriptcontext.doc.Objects.GripUpdate(rhobj, True)
248 | scriptcontext.doc.Views.Redraw()
249 | return rc
250 |
251 |
252 | def ObjectGripsOn(object_id):
253 | """Verifies that an object's grips are turned on
254 | Parameters:
255 | object_id (guid): identifier of the object
256 | Returns:
257 | bool: True or False indicating Grips state
258 | None: on error
259 | Example:
260 | import rhinoscriptsyntax as rs
261 | obj = rs.GetObject("Select object")
262 | if rs.ObjectGripsOn(obj):
263 | print("Grip count = {}".format(rs.ObjectGripCount(obj)))
264 | See Also:
265 | EnableObjectGrips
266 | ObjectGripCount
267 | ObjectGripsSelected
268 | SelectObjectGrips
269 | UnselectObjectGrips
270 | """
271 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
272 | return rhobj.GripsOn
273 |
274 |
275 | def ObjectGripsSelected(object_id):
276 | """Verifies that an object's grips are turned on and at least one grip
277 | is selected
278 | Parameters:
279 | object_id (guid): identifier of the object
280 | Returns:
281 | bool: True or False indicating success or failure
282 | Example:
283 | import rhinoscriptsyntax as rs
284 | obj = rs.GetObject("Select object")
285 | if rs.ObjectGripsSelected(obj):
286 | rs.UnselectObjectGrips( obj )
287 | See Also:
288 | EnableObjectGrips
289 | ObjectGripCount
290 | ObjectGripsOn
291 | SelectObjectGrips
292 | UnselectObjectGrips
293 | """
294 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
295 | if not rhobj.GripsOn: return False
296 | grips = rhobj.GetGrips()
297 | if grips is None: return False
298 | for grip in grips:
299 | if grip.IsSelected(False): return True
300 | return False
301 |
302 |
303 | def PrevObjectGrip(object_id, index, direction=0, enable=True):
304 | """Returns the previous grip index from a specified grip index of an object
305 | Parameters:
306 | object_id (guid): identifier of the object
307 | index (number): zero based grip index from which to get the previous grip index
308 | direction ([number, number], optional): direction to get the next grip index (0=U, 1=V)
309 | enable (bool, optional): if True, the next grip index found will be selected
310 | Returns:
311 | number: index of the next grip on success
312 | None: on failure
313 | Example:
314 | import rhinoscriptsyntax as rs
315 | object_id = rs.GetObject("Select curve", rs.filter.curve)
316 | if object_id:
317 | rs.EnableObjectGrips(object_id)
318 | count = rs.ObjectGripCount(object_id)
319 | for i in range(count-1, 0, -2):
320 | rs.PrevObjectGrip(object_id, i, 0, True)
321 | See Also:
322 | EnableObjectGrips
323 | NextObjectGrip
324 | """
325 | return __neighborgrip(-1, object_id, index, direction, enable)
326 |
327 |
328 | def SelectedObjectGrips(object_id):
329 | """Returns a list of grip indices indentifying an object's selected grips
330 | Parameters:
331 | object_id (guid): identifier of the object
332 | Returns:
333 | list(number): list of indices on success
334 | None: on failure or if no grips are selected
335 | Example:
336 | import rhinoscriptsyntax as rs
337 | obj = rs.GetObject("Select curve", rs.filter.curve)
338 | if obj:
339 | rs.EnableObjectGrips( obj )
340 | count = rs.ObjectGripCount( obj )
341 | for i in range(0,count,2):
342 | rs.SelectObjectGrip( obj, i )
343 | grips = rs.SelectedObjectGrips(obj)
344 | if grips: print(len(grips{}).format("grips selected"))
345 | See Also:
346 | EnableObjectGrips
347 | SelectObjectGrip
348 | SelectObjectGrips
349 | """
350 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
351 | if not rhobj.GripsOn: return None
352 | grips = rhobj.GetGrips()
353 | rc = []
354 | if grips:
355 | for i in compat.RANGE(grips.Length):
356 | if grips[i].IsSelected(False): rc.append(i)
357 | return rc
358 |
359 |
360 | def SelectObjectGrip(object_id, index):
361 | """Selects a single grip owned by an object. If the object's grips are
362 | not turned on, the grips will not be selected
363 | Parameters:
364 | object_id (guid) identifier of the object
365 | index (number): index of the grip to select
366 | Returns:
367 | bool: True or False indicating success or failure
368 | Example:
369 | import rhinoscriptsyntax as rs
370 | obj = rs.GetObject("Select curve", rs.filter.curve)
371 | if obj:
372 | rs.EnableObjectGrips( obj )
373 | count = rs.ObjectGripCount( obj )
374 | for i in range(0,count,2): rs.SelectObjectGrip(obj,i)
375 | See Also:
376 | EnableObjectGrips
377 | ObjectGripCount
378 | SelectObjectGrips
379 | """
380 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
381 | if not rhobj.GripsOn: return False
382 | grips = rhobj.GetGrips()
383 | if grips is None: return False
384 | if index<0 or index>=grips.Length: return False
385 | grip = grips[index]
386 | if grip.Select(True,True)>0:
387 | scriptcontext.doc.Views.Redraw()
388 | return True
389 | return False
390 |
391 |
392 | def SelectObjectGrips(object_id):
393 | """Selects an object's grips. If the object's grips are not turned on,
394 | they will not be selected
395 | Parameters:
396 | object_id (guid): identifier of the object
397 | Returns:
398 | number: Number of grips selected on success
399 | None: on failure
400 | Example:
401 | import rhinoscriptsyntax as rs
402 | obj = rs.GetObject("Select object")
403 | if rs.ObjectGripsSelected(obj)==False:
404 | rs.SelectObjectGrips( obj )
405 | See Also:
406 | EnableObjectGrips
407 | ObjectGripCount
408 | SelectObjectGrip
409 | """
410 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
411 | if not rhobj.GripsOn: return scriptcontext.errorhandler()
412 | grips = rhobj.GetGrips()
413 | if grips is None: return scriptcontext.errorhandler()
414 | count = 0
415 | for grip in grips:
416 | if grip.Select(True,True)>0: count+=1
417 | if count>0:
418 | scriptcontext.doc.Views.Redraw()
419 | return count
420 | return scriptcontext.errorhandler()
421 |
422 |
423 | def UnselectObjectGrip(object_id, index):
424 | """Unselects a single grip owned by an object. If the object's grips are
425 | not turned on, the grips will not be unselected
426 | Parameters:
427 | object_id (guid): identifier of the object
428 | index (number): index of the grip to unselect
429 | Returns:
430 | bool: True or False indicating success or failure
431 | Example:
432 | import rhinoscriptsyntax as rs
433 | obj = rs.GetObject("Select curve", rs.filter.curve)
434 | if obj:
435 | rs.EnableObjectGrips( obj )
436 | count = rs.ObjectGripCount(obj)
437 | for i in range(0,count,2):
438 | rs.UnselectObjectGrip( obj, i )
439 | See Also:
440 | EnableObjectGrips
441 | ObjectGripCount
442 | UnselectObjectGrips
443 | """
444 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
445 | if not rhobj.GripsOn: return False
446 | grips = rhobj.GetGrips()
447 | if grips is None: return False
448 | if index<0 or index>=grips.Length: return False
449 | grip = grips[index]
450 | if grip.Select(False)==0:
451 | scriptcontext.doc.Views.Redraw()
452 | return True
453 | return False
454 |
455 |
456 | def UnselectObjectGrips(object_id):
457 | """Unselects an object's grips. Note, the grips will not be turned off.
458 | Parameters:
459 | object_id (guid): identifier of the object
460 | Returns:
461 | number: Number of grips unselected on success
462 | None: on failure
463 | Example:
464 | import rhinoscriptsyntax as rs
465 | obj = rs.GetObject("Select object")
466 | if rs.ObjectGripsSelected(obj): rs.UnselectObjectGrips(obj)
467 | See Also:
468 | EnableObjectGrips
469 | ObjectGripCount
470 | UnselectObjectGrip
471 | """
472 | rhobj = rhutil.coercerhinoobject(object_id, True, True)
473 | if not rhobj.GripsOn: return scriptcontext.errorhandler()
474 | grips = rhobj.GetGrips()
475 | if grips is None: return scriptcontext.errorhandler()
476 | count = 0
477 | for grip in grips:
478 | if grip.Select(False)==0: count += 1
479 | if count>0:
480 | scriptcontext.doc.Views.Redraw()
481 | return count
482 | return scriptcontext.errorhandler()
483 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/material.py:
--------------------------------------------------------------------------------
```python
1 | import Rhino
2 | import Rhino.DocObjects
3 |
4 | import scriptcontext
5 |
6 | from rhinoscript import utility as rhutil
7 | from rhinoscript.layer import __getlayer
8 |
9 |
10 | def AddMaterialToLayer(layer):
11 | """Add material to a layer and returns the new material's index. If the
12 | layer already has a material, then the layer's current material index is
13 | returned
14 | Parameters:
15 | layer (str): name of an existing layer.
16 | Returns:
17 | number: Material index of the layer if successful
18 | None: if not successful or on error
19 | Example:
20 | import rhinoscriptsyntax as rs
21 | layer = rs.CurrentLayer()
22 | index = rs.LayerMaterialIndex(layer)
23 | if index==-1: index = rs.AddMaterialToLayer(layer)
24 | See Also:
25 | LayerMaterialIndex
26 | IsMaterialDefault
27 | """
28 | layer = __getlayer(layer, True)
29 | if layer.RenderMaterialIndex>-1: return layer.RenderMaterialIndex
30 | material_index = scriptcontext.doc.Materials.Add()
31 | layer.RenderMaterialIndex = material_index
32 | scriptcontext.doc.Views.Redraw()
33 | return material_index
34 | #return scriptcontext.errorhandler()
35 |
36 |
37 | def AddMaterialToObject(object_id):
38 | """Adds material to an object and returns the new material's index. If the
39 | object already has a material, the the object's current material index is
40 | returned.
41 | Parameters:
42 | object_id (guid): identifier of an object
43 | Returns:
44 | number: material index of the object
45 | Example:
46 | import rhinoscriptsyntax as rs
47 | obj = rs.GetObject()
48 | if obj:
49 | index = rs.ObjectMaterialIndex(obj)
50 | if index==-1: index = rs.AddMaterialToObject(obj)
51 | See Also:
52 | IsMaterialDefault
53 | ObjectMaterialIndex
54 | ObjectMaterialSource
55 | """
56 | rhino_object = rhutil.coercerhinoobject(object_id, True, True)
57 | attr = rhino_object.Attributes
58 | if attr.MaterialSource!=Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject:
59 | attr.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject
60 | scriptcontext.doc.Objects.ModifyAttributes(rhino_object, attr, True)
61 | attr = rhino_object.Attributes
62 | material_index = attr.MaterialIndex
63 | if material_index>-1: return material_index
64 | material_index = scriptcontext.doc.Materials.Add()
65 | attr.MaterialIndex = material_index
66 | scriptcontext.doc.Objects.ModifyAttributes(rhino_object, attr, True)
67 | return material_index
68 |
69 |
70 | def CopyMaterial(source_index, destination_index):
71 | """Copies definition of a source material to a destination material
72 | Parameters:
73 | source_index, destination_index (number): indices of materials to copy
74 | Returns:
75 | bool: True or False indicating success or failure
76 | Example:
77 | import rhinoscriptsyntax as rs
78 | src = rs.LayerMaterialIndex("Default")
79 | dest = rs.LayerMaterialIndex(rs.CurrentLayer())
80 | if src>=0 and dest>=0 and src!=dest:
81 | rs.CopyMaterial( src, dest )
82 | See Also:
83 | LayerMaterialIndex
84 | ObjectMaterialIndex
85 | """
86 | if source_index==destination_index: return False
87 | source = scriptcontext.doc.Materials[source_index]
88 | if source is None: return False
89 | rc = scriptcontext.doc.Materials.Modify(source, destination_index, True)
90 | if rc: scriptcontext.doc.Views.Redraw()
91 | return rc
92 |
93 |
94 | def IsMaterialDefault(material_index):
95 | """Verifies a material is a copy of Rhino's built-in "default" material.
96 | The default material is used by objects and layers that have not been
97 | assigned a material.
98 | Parameters:
99 | material_index (number): the zero-based material index
100 | Returns:
101 | bool: True or False indicating success or failure
102 | Example:
103 | import rhinoscriptsyntax as rs
104 | obj = rs.GetObject()
105 | if obj:
106 | index = rs.ObjectMaterialIndex(obj)
107 | if rs.IsMaterialDefault(index):
108 | print("Object is assigned default material.")
109 | else:
110 | print("Object is not assigned default material.")
111 | See Also:
112 | LayerMaterialIndex
113 | ObjectMaterialIndex
114 | """
115 | mat = scriptcontext.doc.Materials[material_index]
116 | return mat and mat.IsDefaultMaterial
117 |
118 |
119 | def IsMaterialReference(material_index):
120 | """Verifies a material is referenced from another file
121 | Parameters:
122 | material_index (number): the zero-based material index
123 | Returns:
124 | bool: True or False indicating success or failure
125 | Example:
126 | import rhinoscriptsyntax as rs
127 | obj = rs.GetObject()
128 | if obj:
129 | index = rs.ObjectMaterialIndex(obj)
130 | if rs.IsMaterialReference(index):
131 | print("The material is referenced from another file.")
132 | else:
133 | print("The material is not referenced from another file.")
134 | See Also:
135 | IsLayerReference
136 | IsLightReference
137 | IsObjectReference
138 | """
139 | mat = scriptcontext.doc.Materials[material_index]
140 | return mat and mat.IsReference
141 |
142 |
143 | def MatchMaterial(source, destination):
144 | """Copies the material definition from one material to one or more objects
145 | Parameters:
146 | source (number|guid): source material index -or- identifier of the source object.
147 | The object must have a material assigned
148 | destination ([guid, ...]) identifiers(s) of the destination object(s)
149 | Returns:
150 | number: number of objects that were modified if successful
151 | None: if not successful or on error
152 | Example:
153 | import rhinoscriptsyntax as rs
154 | obj = rs.GetObject("Select source object")
155 | if obj and rs.ObjectMaterialIndex(obj)>-1:
156 | objects = rs.GetObjects("Select destination objects")
157 | if objects: rs.MatchMaterial( obj, objects )
158 | See Also:
159 | CopyMaterial
160 | LayerMaterialIndex
161 | ObjectMaterialIndex
162 | """
163 | source_id = rhutil.coerceguid(source)
164 | source_mat = None
165 | if source_id:
166 | rhobj = rhutil.coercerhinoobject(source_id, True, True)
167 | source = rhobj.Attributes.MaterialIndex
168 | mat = scriptcontext.doc.Materials[source]
169 | if not mat: return scriptcontext.errorhandler()
170 | destination_id = rhutil.coerceguid(destination)
171 | if destination_id: destination = [destination]
172 | ids = [rhutil.coerceguid(d) for d in destination]
173 | rc = 0
174 | for id in ids:
175 | rhobj = scriptcontext.doc.Objects.Find(id)
176 | if rhobj:
177 | rhobj.Attributes.MaterialIndex = source
178 | rhobj.Attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject
179 | rhobj.CommitChanges()
180 | rc += 1
181 | if rc>0: scriptcontext.doc.Views.Redraw()
182 | return rc
183 |
184 |
185 | def MaterialBump(material_index, filename=None):
186 | """Returns or modifies a material's bump bitmap filename
187 | Parameters:
188 | material_index (number): zero based material index
189 | filename (str, optional): the bump bitmap filename
190 | Returns:
191 | str: if filename is not specified, the current bump bitmap filename
192 | str: if filename is specified, the previous bump bitmap filename
193 | None: if not successful or on error
194 | Example:
195 | import rhinoscriptsyntax as rs
196 | obj = rs.GetObject("Select object")
197 | if obj:
198 | index = rs.ObjectMaterialIndex(obj)
199 | if index>-1:
200 | rs.MaterialBump( index, "C:\\Users\\Steve\\Desktop\\bumpimage.png" )
201 | See Also:
202 | MaterialColor
203 | MaterialName
204 | MaterialReflectiveColor
205 | MaterialShine
206 | MaterialTexture
207 | MaterialTransparency
208 | """
209 | mat = scriptcontext.doc.Materials[material_index]
210 | if mat is None: return scriptcontext.errorhandler()
211 | texture = mat.GetBumpTexture()
212 | rc = texture.FileName if texture else ""
213 | if filename:
214 | mat.SetBumpTexture(filename)
215 | mat.CommitChanges()
216 | scriptcontext.doc.Views.Redraw()
217 | return rc
218 |
219 |
220 | def MaterialColor(material_index, color=None):
221 | """Returns or modifies a material's diffuse color.
222 | Parameters:
223 | material_index (number): zero based material index
224 | color (color, optional): the new color value
225 | Returns:
226 | color: if color is not specified, the current material color
227 | color: if color is specified, the previous material color
228 | None: on error
229 | Example:
230 | import rhinoscriptsyntax as rs
231 | obj = rs.GetObject("Select object")
232 | if obj:
233 | index = rs.ObjectMaterialIndex(obj)
234 | if index>-1:
235 | rs.MaterialColor( index, (127, 255, 191) )
236 | See Also:
237 | MaterialBump
238 | MaterialName
239 | MaterialReflectiveColor
240 | MaterialShine
241 | MaterialTexture
242 | MaterialTransparency
243 | """
244 | mat = scriptcontext.doc.Materials[material_index]
245 | if mat is None: return scriptcontext.errorhandler()
246 | rc = mat.DiffuseColor
247 | color = rhutil.coercecolor(color)
248 | if color:
249 | mat.DiffuseColor = color
250 | mat.CommitChanges()
251 | scriptcontext.doc.Views.Redraw()
252 | return rc
253 |
254 |
255 | def MaterialEnvironmentMap(material_index, filename=None):
256 | """Returns or modifies a material's environment bitmap filename.
257 | Parameters:
258 | material_index (number): zero based material index
259 | filename (str, optional): the environment bitmap filename
260 | Returns:
261 | str: if filename is not specified, the current environment bitmap filename
262 | str: if filename is specified, the previous environment bitmap filename
263 | None: if not successful or on error
264 | Example:
265 | import rhinoscriptsyntax as rs
266 | obj = rs.GetObject("Select object")
267 | if obj:
268 | index = rs.ObjectMaterialIndex(obj)
269 | if index>-1:
270 | rs.MaterialEnvironmentMap( index, "C:\\Users\\Steve\\Desktop\\emapimage.png" )
271 | See Also:
272 | MaterialBump
273 | MaterialTexture
274 | MaterialTransparencyMap
275 | """
276 | mat = scriptcontext.doc.Materials[material_index]
277 | if mat is None: return scriptcontext.errorhandler()
278 | texture = mat.GetEnvironmentTexture()
279 | rc = texture.FileName if texture else ""
280 | if filename:
281 | mat.SetEnvironmentTexture(filename)
282 | mat.CommitChanges()
283 | scriptcontext.doc.Views.Redraw()
284 | return rc
285 |
286 |
287 | def MaterialName(material_index, name=None):
288 | """Returns or modifies a material's user defined name
289 | Parameters:
290 | material_index (number): zero based material index
291 | name (str, optional): the new name
292 | Returns:
293 | str: if name is not specified, the current material name
294 | str: if name is specified, the previous material name
295 | None: on error
296 | Example:
297 | import rhinoscriptsyntax as rs
298 | obj = rs.GetObject("Select object")
299 | if obj:
300 | index = rs.ObjectMaterialIndex(obj)
301 | if index>-1:
302 | rs.MaterialName( index, "Fancy_Material" )
303 | See Also:
304 | MaterialBump
305 | MaterialColor
306 | MaterialReflectiveColor
307 | MaterialShine
308 | MaterialTexture
309 | MaterialTransparency
310 | """
311 | mat = scriptcontext.doc.Materials[material_index]
312 | if mat is None: return scriptcontext.errorhandler()
313 | rc = mat.Name
314 | if name:
315 | mat.Name = name
316 | mat.CommitChanges()
317 | return rc
318 |
319 |
320 | def MaterialReflectiveColor(material_index, color=None):
321 | """Returns or modifies a material's reflective color.
322 | Parameters:
323 | material_index (number): zero based material index
324 | color (color, optional): the new color value
325 | Returns:
326 | color: if color is not specified, the current material reflective color
327 | color: if color is specified, the previous material reflective color
328 | None: on error
329 | Example:
330 | import rhinoscriptsyntax as rs
331 | obj = rs.GetObject("Select object")
332 | if obj:
333 | index = rs.ObjectMaterialIndex(obj)
334 | if index>-1:
335 | rs.MaterialReflectiveColor( index, (191, 191, 255) )
336 | See Also:
337 | MaterialBump
338 | MaterialColor
339 | MaterialName
340 | MaterialShine
341 | MaterialTexture
342 | MaterialTransparency
343 | """
344 | mat = scriptcontext.doc.Materials[material_index]
345 | if mat is None: return scriptcontext.errorhandler()
346 | rc = mat.ReflectionColor
347 | color = rhutil.coercecolor(color)
348 | if color:
349 | mat.ReflectionColor = color
350 | mat.CommitChanges()
351 | scriptcontext.doc.Views.Redraw()
352 | return rc
353 |
354 |
355 | def MaterialShine(material_index, shine=None):
356 | """Returns or modifies a material's shine value
357 | Parameters:
358 | material_index (number): zero based material index
359 | shine (number, optional): the new shine value. A material's shine value ranges from 0.0 to 255.0, with
360 | 0.0 being matte and 255.0 being glossy
361 | Returns:
362 | number: if shine is not specified, the current material shine value
363 | number: if shine is specified, the previous material shine value
364 | None: on error
365 | Example:
366 | import rhinoscriptsyntax as rs
367 | MAX_SHINE = 255.0
368 | obj = rs.GetObject("Select object")
369 | if obj:
370 | index = rs.ObjectMaterialIndex(obj)
371 | if index>-1:
372 | rs.MaterialShine( index, MAX_SHINE/2 )
373 | See Also:
374 | MaterialBump
375 | MaterialColor
376 | MaterialName
377 | MaterialReflectiveColor
378 | MaterialTexture
379 | MaterialTransparency
380 | """
381 | mat = scriptcontext.doc.Materials[material_index]
382 | if mat is None: return scriptcontext.errorhandler()
383 | rc = mat.Shine
384 | if shine:
385 | mat.Shine = shine
386 | mat.CommitChanges()
387 | scriptcontext.doc.Views.Redraw()
388 | return rc
389 |
390 |
391 | def MaterialTexture(material_index, filename=None):
392 | """Returns or modifies a material's texture bitmap filename
393 | Parameters:
394 | material_index (number): zero based material index
395 | filename (str, optional): the texture bitmap filename
396 | Returns:
397 | str: if filename is not specified, the current texture bitmap filename
398 | str: if filename is specified, the previous texture bitmap filename
399 | None: if not successful or on error
400 | Example:
401 | import rhinoscriptsyntax as rs
402 | obj = rs.GetObject("Select object")
403 | if obj:
404 | index = rs.ObjectMaterialIndex(obj)
405 | if index>-1:
406 | rs.MaterialTexture( index, "C:\\Users\\Steve\\Desktop\\textureimage.png" )
407 | See Also:
408 | MaterialBump
409 | MaterialColor
410 | MaterialName
411 | MaterialReflectiveColor
412 | MaterialShine
413 | MaterialTransparency
414 | """
415 | mat = scriptcontext.doc.Materials[material_index]
416 | if mat is None: return scriptcontext.errorhandler()
417 | texture = mat.GetBitmapTexture()
418 | rc = texture.FileName if texture else ""
419 | if filename:
420 | mat.SetBitmapTexture(filename)
421 | mat.CommitChanges()
422 | scriptcontext.doc.Views.Redraw()
423 | return rc
424 |
425 |
426 | def MaterialTransparency(material_index, transparency=None):
427 | """Returns or modifies a material's transparency value
428 | Parameters:
429 | material_index (number): zero based material index
430 | transparency (number, optional): the new transparency value. A material's transparency value ranges from 0.0 to 1.0, with
431 | 0.0 being opaque and 1.0 being transparent
432 | Returns:
433 | number: if transparency is not specified, the current material transparency value
434 | number: if transparency is specified, the previous material transparency value
435 | None: on error
436 | Example:
437 | import rhinoscriptsyntax as rs
438 | obj = rs.GetObject("Select object")
439 | if obj:
440 | index = rs.ObjectMaterialIndex(obj)
441 | if index>-1:
442 | rs.MaterialTransparency( index, 0.50 )
443 | See Also:
444 | MaterialBump
445 | MaterialColor
446 | MaterialName
447 | MaterialReflectiveColor
448 | MaterialShine
449 | MaterialTexture
450 | """
451 | mat = scriptcontext.doc.Materials[material_index]
452 | if mat is None: return scriptcontext.errorhandler()
453 | rc = mat.Transparency
454 | if transparency:
455 | mat.Transparency = transparency
456 | mat.CommitChanges()
457 | scriptcontext.doc.Views.Redraw()
458 | return rc
459 |
460 |
461 | def MaterialTransparencyMap(material_index, filename=None):
462 | """Returns or modifies a material's transparency bitmap filename
463 | Parameters:
464 | material_index (number): zero based material index
465 | filename (str, optional): the transparency bitmap filename
466 | Returns:
467 | str: if filename is not specified, the current transparency bitmap filename
468 | str: if filename is specified, the previous transparency bitmap filename
469 | None: if not successful or on error
470 | Example:
471 | import rhinoscriptsyntax as rs
472 | obj = rs.GetObject("Select object")
473 | if obj:
474 | index = rs.ObjectMaterialIndex(obj)
475 | if index>-1:
476 | rs.MaterialTransparencyMap( index, "C:\\Users\\Steve\\Desktop\\texture.png" )
477 | See Also:
478 | MaterialBump
479 | MaterialEnvironmentMap
480 | MaterialTexture
481 | """
482 | mat = scriptcontext.doc.Materials[material_index]
483 | if mat is None: return scriptcontext.errorhandler()
484 | texture = mat.GetTransparencyTexture()
485 | rc = texture.FileName if texture else ""
486 | if filename:
487 | mat.SetTransparencyTexture(filename)
488 | mat.CommitChanges()
489 | scriptcontext.doc.Views.Redraw()
490 | return rc
491 |
492 |
493 | def ResetMaterial(material_index):
494 | """Resets a material to Rhino's default material
495 | Parameters:
496 | material_index (number) zero based material index
497 | Returns:
498 | bool: True or False indicating success or failure
499 | Example:
500 | import rhinoscriptsyntax as rs
501 | obj = rs.GetObject("Select object")
502 | if obj:
503 | index = rs.ObjectMaterialIndex(obj)
504 | if index>-1: rs.ResetMaterial(index)
505 | See Also:
506 | LayerMaterialIndex
507 | ObjectMaterialIndex
508 | """
509 | mat = scriptcontext.doc.Materials[material_index]
510 | if mat is None: return False
511 | rc = scriptcontext.doc.Materials.ResetMaterial(material_index)
512 | scriptcontext.doc.Views.Redraw()
513 | return rc
514 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/plane.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import Rhino.Geometry
4 |
5 | import scriptcontext
6 |
7 | from rhinoscript import utility as rhutil
8 |
9 |
10 | def DistanceToPlane(plane, point):
11 | """Returns the distance from a 3D point to a plane
12 | Parameters:
13 | plane (plane): the plane
14 | point (point): List of 3 numbers or Point3d
15 | Returns:
16 | number: The distance if successful, otherwise None
17 | Example:
18 | import rhinoscriptsyntax as rs
19 | point = rs.GetPoint("Point to test")
20 | if point:
21 | plane = rs.ViewCPlane()
22 | if plane:
23 | distance = rs.DistanceToPlane(plane, point)
24 | if distance is not None:
25 | print("Distance to plane: {}".format(distance))
26 | See Also:
27 | Distance
28 | PlaneClosestPoint
29 | """
30 | plane = rhutil.coerceplane(plane, True)
31 | point = rhutil.coerce3dpoint(point, True)
32 | return plane.DistanceTo(point)
33 |
34 |
35 | def EvaluatePlane(plane, parameter):
36 | """Evaluates a plane at a U,V parameter
37 | Parameters:
38 | plane (plane): the plane to evaluate
39 | parameter ([number, number]): list of two numbers defining the U,V parameter to evaluate
40 | Returns:
41 | point: Point3d on success
42 | Example:
43 | import rhinoscriptsyntax as rs
44 | view = rs.CurrentView()
45 | plane = rs.ViewCPlane(view)
46 | point = rs.EvaluatePlane(plane, (5,5))
47 | rs.AddPoint( point )
48 | See Also:
49 | PlaneClosestPoint
50 | """
51 | plane = rhutil.coerceplane(plane, True)
52 | return plane.PointAt(parameter[0], parameter[1])
53 |
54 |
55 | def IntersectPlanes(plane1, plane2, plane3):
56 | """Calculates the intersection of three planes
57 | Parameters:
58 | plane1 (plane): the 1st plane to intersect
59 | plane2 (plane): the 2nd plane to intersect
60 | plane3 (plane): the 3rd plane to intersect
61 | Returns:
62 | point: the intersection point between the 3 planes on success
63 | None: on error
64 | Example:
65 | import rhinoscriptsyntax as rs
66 | plane1 = rs.WorldXYPlane()
67 | plane2 = rs.WorldYZPlane()
68 | plane3 = rs.WorldZXPlane()
69 | point = rs.IntersectPlanes(plane1, plane2, plane3)
70 | if point: rs.AddPoint(point)
71 | See Also:
72 | LineLineIntersection
73 | LinePlaneIntersection
74 | PlanePlaneIntersection
75 | """
76 | plane1 = rhutil.coerceplane(plane1, True)
77 | plane2 = rhutil.coerceplane(plane2, True)
78 | plane3 = rhutil.coerceplane(plane3, True)
79 | rc, point = Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane1, plane2, plane3)
80 | if rc: return point
81 |
82 |
83 | def MovePlane(plane, origin):
84 | """Moves the origin of a plane
85 | Parameters:
86 | plane (plane): Plane or ConstructionPlane
87 | origin (point): Point3d or list of three numbers
88 | Returns:
89 | plane: moved plane
90 | Example:
91 | import rhinoscriptsyntax as rs
92 | origin = rs.GetPoint("CPlane origin")
93 | if origin:
94 | plane = rs.ViewCPlane()
95 | plane = rs.MovePlane(plane,origin)
96 | rs.ViewCplane(plane)
97 | See Also:
98 | PlaneFromFrame
99 | PlaneFromNormal
100 | RotatePlane
101 | """
102 | plane = rhutil.coerceplane(plane, True)
103 | origin = rhutil.coerce3dpoint(origin, True)
104 | rc = Rhino.Geometry.Plane(plane)
105 | rc.Origin = origin
106 | return rc
107 |
108 |
109 | def PlaneClosestPoint(plane, point, return_point=True):
110 | """Returns the point on a plane that is closest to a test point.
111 | Parameters:
112 | plane (plane): The plane
113 | point (point): The 3-D point to test.
114 | return_point (bool, optional): If omitted or True, then the point on the plane
115 | that is closest to the test point is returned. If False, then the
116 | parameter of the point on the plane that is closest to the test
117 | point is returned.
118 | Returns:
119 | point: If return_point is omitted or True, then the 3-D point
120 | point: If return_point is False, then an array containing the U,V parameters
121 | of the point
122 | None: if not successful, or on error.
123 | Example:
124 | import rhinoscriptsyntax as rs
125 | point = rs.GetPoint("Point to test")
126 | if point:
127 | plane = rs.ViewCPlane()
128 | if plane:
129 | print(rs.PlaneClosestPoint(plane, point))
130 | See Also:
131 | DistanceToPlane
132 | EvaluatePlane
133 | """
134 | plane = rhutil.coerceplane(plane, True)
135 | point = rhutil.coerce3dpoint(point, True)
136 | if return_point:
137 | return plane.ClosestPoint(point)
138 | else:
139 | rc, s, t = plane.ClosestParameter(point)
140 | if rc: return s, t
141 |
142 |
143 | def PlaneCurveIntersection(plane, curve, tolerance=None):
144 | """Intersect an infinite plane and a curve object
145 | Parameters:
146 | plane (plane): The plane to intersect.
147 | curve (guid): The identifier of the curve object
148 | torerance (number, optional): The intersection tolerance. If omitted, the document's absolute tolerance is used.
149 | Returns:
150 | A list of intersection information tuple if successful. The list will contain one or more of the following tuple:
151 |
152 | Element Type Description
153 |
154 | [0] Number The intersection event type, either Point (1) or Overlap (2).
155 |
156 | [1] Point3d If the event type is Point (1), then the intersection point on the curve.
157 | If the event type is Overlap (2), then intersection start point on the curve.
158 |
159 | [2] Point3d If the event type is Point (1), then the intersection point on the curve.
160 | If the event type is Overlap (2), then intersection end point on the curve.
161 |
162 | [3] Point3d If the event type is Point (1), then the intersection point on the plane.
163 | If the event type is Overlap (2), then intersection start point on the plane.
164 |
165 | [4] Point3d If the event type is Point (1), then the intersection point on the plane.
166 |
167 | If the event type is Overlap (2), then intersection end point on the plane.
168 |
169 | [5] Number If the event type is Point (1), then the curve parameter.
170 | If the event type is Overlap (2), then the start value of the curve parameter range.
171 |
172 | [6] Number If the event type is Point (1), then the curve parameter.
173 | If the event type is Overlap (2), then the end value of the curve parameter range.
174 |
175 | [7] Number If the event type is Point (1), then the U plane parameter.
176 | If the event type is Overlap (2), then the U plane parameter for curve at (n, 5).
177 |
178 | [8] Number If the event type is Point (1), then the V plane parameter.
179 | If the event type is Overlap (2), then the V plane parameter for curve at (n, 5).
180 |
181 | [9] Number If the event type is Point (1), then the U plane parameter.
182 | If the event type is Overlap (2), then the U plane parameter for curve at (n, 6).
183 |
184 | [10] Number If the event type is Point (1), then the V plane parameter.
185 | If the event type is Overlap (2), then the V plane parameter for curve at (n, 6).
186 |
187 | None: on error
188 | Example:
189 | import rhinoscriptsyntax as rs
190 | curve = rs.GetObject("Select curve", rs.filter.curve)
191 | if curve:
192 | plane = rs.WorldXYPlane()
193 | intersections = rs.PlaneCurveIntersection(plane, curve)
194 | if intersections:
195 | for intersection in intersections:
196 | rs.AddPoint(intersection[1])
197 | See Also:
198 | IntersectPlanes
199 | PlanePlaneIntersection
200 | PlaneSphereIntersection
201 | """
202 | plane = rhutil.coerceplane(plane, True)
203 | curve = rhutil.coercecurve(curve, -1, True)
204 | if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
205 | intersections = Rhino.Geometry.Intersect.Intersection.CurvePlane(curve, plane, tolerance)
206 | if intersections:
207 | rc = []
208 | for intersection in intersections:
209 | a = 1
210 | if intersection.IsOverlap: a = 2
211 | b = intersection.PointA
212 | c = intersection.PointA2
213 | d = intersection.PointB
214 | e = intersection.PointB2
215 | f = intersection.ParameterA
216 | g = intersection.ParameterB
217 | h = intersection.OverlapA[0]
218 | i = intersection.OverlapA[1]
219 | j = intersection.OverlapB[0]
220 | k = intersection.OverlapB[1]
221 | rc.append( (a,b,c,d,e,f,g,h,i,j,k) )
222 | return rc
223 |
224 |
225 | def PlaneEquation(plane):
226 | """Returns the equation of a plane as a tuple of four numbers. The standard
227 | equation of a plane with a non-zero vector is Ax+By+Cz+D=0
228 | Parameters:
229 | plane (plane): the plane to deconstruct
230 | Returns:
231 | tuple(number, number, number, number): containing four numbers that represent the coefficients of the equation (A, B, C, D) if successful
232 | None: if not successful
233 | Example:
234 | import rhinoscriptsyntax as rs
235 | plane = rs.ViewCPlane()
236 | equation = rs.PlaneEquation(plane)
237 | print("A = {}".format(equation[0]))
238 | print("B = {}".format(equation[1]))
239 | print("C = {}".format(equation[2]))
240 | print("D = {}".format(equation[3]))
241 | See Also:
242 | PlaneFromFrame
243 | PlaneFromNormal
244 | PlaneFromPoints
245 | """
246 | plane = rhutil.coerceplane(plane, True)
247 | rc = plane.GetPlaneEquation()
248 | return rc[0], rc[1], rc[2], rc[3]
249 |
250 |
251 | def PlaneFitFromPoints(points):
252 | """Returns a plane that was fit through an array of 3D points.
253 | Parameters:
254 | points (point): An array of 3D points.
255 | Returns:
256 | plane: The plane if successful
257 | None: if not successful
258 | Example:
259 | import rhinoscriptsyntax as rs
260 | points = rs.GetPoints()
261 | if points:
262 | plane = rs.PlaneFitFromPoints(points)
263 | if plane:
264 | magX = plane.XAxis.Length
265 | magY = plane.YAxis.Length
266 | rs.AddPlaneSurface( plane, magX, magY )
267 | See Also:
268 | PlaneFromFrame
269 | PlaneFromNormal
270 | PlaneFromPoints
271 | """
272 | points = rhutil.coerce3dpointlist(points, True)
273 | rc, plane = Rhino.Geometry.Plane.FitPlaneToPoints(points)
274 | if rc==Rhino.Geometry.PlaneFitResult.Success: return plane
275 |
276 |
277 | def PlaneFromFrame(origin, x_axis, y_axis):
278 | """Construct a plane from a point, and two vectors in the plane.
279 | Parameters:
280 | origin (point): A 3D point identifying the origin of the plane.
281 | x_axis (vector): A non-zero 3D vector in the plane that determines the X axis
282 | direction.
283 | y_axis (vector): A non-zero 3D vector not parallel to x_axis that is used
284 | to determine the Y axis direction. Note, y_axis does not
285 | have to be perpendicular to x_axis.
286 | Returns:
287 | plane: The plane if successful.
288 | Example:
289 | import rhinoscriptsyntax as rs
290 | origin = rs.GetPoint("CPlane origin")
291 | if origin:
292 | xaxis = (1,0,0)
293 | yaxis = (0,0,1)
294 | plane = rs.PlaneFromFrame( origin, xaxis, yaxis )
295 | rs.ViewCPlane(None, plane)
296 | See Also:
297 | MovePlane
298 | PlaneFromNormal
299 | PlaneFromPoints
300 | RotatePlane
301 | """
302 | origin = rhutil.coerce3dpoint(origin, True)
303 | x_axis = rhutil.coerce3dvector(x_axis, True)
304 | y_axis = rhutil.coerce3dvector(y_axis, True)
305 | return Rhino.Geometry.Plane(origin, x_axis, y_axis)
306 |
307 |
308 | def PlaneFromNormal(origin, normal, xaxis=None):
309 | """Creates a plane from an origin point and a normal direction vector.
310 | Parameters:
311 | origin (point): A 3D point identifying the origin of the plane.
312 | normal (vector): A 3D vector identifying the normal direction of the plane.
313 | xaxis (vector, optional): optional vector defining the plane's x-axis
314 | Returns:
315 | plane: The plane if successful.
316 | Example:
317 | import rhinoscriptsyntax as rs
318 | origin = rs.GetPoint("CPlane origin")
319 | if origin:
320 | direction = rs.GetPoint("CPlane direction")
321 | if direction:
322 | normal = direction - origin
323 | normal = rs.VectorUnitize(normal)
324 | rs.ViewCPlane( None, rs.PlaneFromNormal(origin, normal) )
325 | See Also:
326 | MovePlane
327 | PlaneFromFrame
328 | PlaneFromPoints
329 | RotatePlane
330 | """
331 | origin = rhutil.coerce3dpoint(origin, True)
332 | normal = rhutil.coerce3dvector(normal, True)
333 | rc = Rhino.Geometry.Plane(origin, normal)
334 | if xaxis:
335 | xaxis = rhutil.coerce3dvector(xaxis, True)
336 | xaxis = Rhino.Geometry.Vector3d(xaxis)#prevent original xaxis parameter from being unitized too
337 | xaxis.Unitize()
338 | yaxis = Rhino.Geometry.Vector3d.CrossProduct(rc.Normal, xaxis)
339 | rc = Rhino.Geometry.Plane(origin, xaxis, yaxis)
340 | return rc
341 |
342 |
343 | def PlaneFromPoints(origin, x, y):
344 | """Creates a plane from three non-colinear points
345 | Parameters:
346 | origin (point): origin point of the plane
347 | x, y (point): points on the plane's x and y axes
348 | Returns:
349 | plane: The plane if successful, otherwise None
350 | Example:
351 | import rhinoscriptsyntax as rs
352 | corners = rs.GetRectangle()
353 | if corners:
354 | rs.ViewCPlane( rs.PlaneFromPoints(corners[0], corners[1], corners[3]))
355 | See Also:
356 | PlaneFromFrame
357 | PlaneFromNormal
358 | """
359 | origin = rhutil.coerce3dpoint(origin, True)
360 | x = rhutil.coerce3dpoint(x, True)
361 | y = rhutil.coerce3dpoint(y, True)
362 | plane = Rhino.Geometry.Plane(origin, x, y)
363 | if plane.IsValid: return plane
364 |
365 |
366 | def PlanePlaneIntersection(plane1, plane2):
367 | """Calculates the intersection of two planes
368 | Parameters:
369 | plane1 (plane): the 1st plane to intersect
370 | plane2 (plane): the 2nd plane to intersect
371 | Returns:
372 | line: a line with two 3d points identifying the starting/ending points of the intersection
373 | None: on error
374 | Example:
375 | import rhinoscriptsyntax as rs
376 | plane1 = rs.WorldXYPlane()
377 | plane2 = rs.WorldYZPlane()
378 | line = rs.PlanePlaneIntersection(plane1, plane2)
379 | if line: rs.AddLine(line[0], line[1])
380 | See Also:
381 | IntersectPlanes
382 | LineLineIntersection
383 | LinePlaneIntersection
384 | """
385 | plane1 = rhutil.coerceplane(plane1, True)
386 | plane2 = rhutil.coerceplane(plane2, True)
387 | rc, line = Rhino.Geometry.Intersect.Intersection.PlanePlane(plane1, plane2)
388 | if rc: return line.From, line.To
389 |
390 |
391 | def PlaneSphereIntersection(plane, sphere_plane, sphere_radius):
392 | """Calculates the intersection of a plane and a sphere
393 | Parameters:
394 | plane (plane): the plane to intersect
395 | sphere_plane (plane): equatorial plane of the sphere. origin of the plane is
396 | the center of the sphere
397 | sphere_radius (number): radius of the sphere
398 | Returns:
399 | list(number, point|plane, number): of intersection results
400 | Element Type Description
401 | [0] number The type of intersection, where 0 = point and 1 = circle.
402 | [1] point or plane If a point intersection, the a Point3d identifying the 3-D intersection location.
403 | If a circle intersection, then the circle's plane. The origin of the plane will be the center point of the circle
404 | [2] number If a circle intersection, then the radius of the circle.
405 | None: on error
406 | Example:
407 | import rhinoscriptsyntax as rs
408 | plane = rs.WorldXYPlane()
409 | radius = 10
410 | results = rs.PlaneSphereIntersection(plane, plane, radius)
411 | if results:
412 | if results[0]==0:
413 | rs.AddPoint(results[1])
414 | else:
415 | rs.AddCircle(results[1], results[2])
416 | See Also:
417 | IntersectPlanes
418 | LinePlaneIntersection
419 | PlanePlaneIntersection
420 | """
421 | plane = rhutil.coerceplane(plane, True)
422 | sphere_plane = rhutil.coerceplane(sphere_plane, True)
423 | sphere = Rhino.Geometry.Sphere(sphere_plane, sphere_radius)
424 | rc, circle = Rhino.Geometry.Intersect.Intersection.PlaneSphere(plane, sphere)
425 | if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Point:
426 | return 0, circle.Center
427 | if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Circle:
428 | return 1, circle.Plane, circle.Radius
429 |
430 |
431 | def PlaneTransform(plane, xform):
432 | """Transforms a plane
433 | Parameters:
434 | plane (plane): Plane to transform
435 | xform (transform): Transformation to apply
436 | Returns:
437 | plane:the resulting plane if successful
438 | None: if not successful
439 | Example:
440 | import rhinoscriptsyntax as rs
441 | plane = rs.ViewCPlane()
442 | xform = rs.XformRotation(45.0, plane.Zaxis, plane.Origin)
443 | plane = rs.PlaneTransform(plane, xform)
444 | rs.ViewCPlane(None, plane)
445 | See Also:
446 | PlaneFromFrame
447 | PlaneFromNormal
448 | PlaneFromPoints
449 | """
450 | plane = rhutil.coerceplane(plane, True)
451 | xform = rhutil.coercexform(xform, True)
452 | rc = Rhino.Geometry.Plane(plane)
453 | if rc.Transform(xform): return rc
454 |
455 |
456 | def RotatePlane(plane, angle_degrees, axis):
457 | """Rotates a plane
458 | Parameters:
459 | plane (plane): Plane to rotate
460 | angle_degrees (number): rotation angle in degrees
461 | axis (vector): Axis of rotation or list of three numbers
462 | Returns:
463 | plane: rotated plane on success
464 | Example:
465 | import rhinoscriptsyntax as rs
466 | plane = rs.ViewCPlane()
467 | rotated = rs.RotatePlane(plane, 45.0, plane.XAxis)
468 | rs.ViewCPlane( None, rotated )
469 | See Also:
470 | MovePlane
471 | PlaneFromFrame
472 | PlaneFromNormal
473 | """
474 | plane = rhutil.coerceplane(plane, True)
475 | axis = rhutil.coerce3dvector(axis, True)
476 | angle_radians = math.radians(angle_degrees)
477 | rc = Rhino.Geometry.Plane(plane)
478 | if rc.Rotate(angle_radians, axis): return rc
479 |
480 |
481 | def WorldXYPlane():
482 | """Returns Rhino's world XY plane
483 | Returns:
484 | plane: Rhino's world XY plane
485 | Example:
486 | import rhinoscriptsyntax as rs
487 | view = rs.CurrentView()
488 | rs.ViewCPlane( view, rs.WorldXYPlane() )
489 | See Also:
490 | WorldYZPlane
491 | WorldZXPlane
492 | """
493 | return Rhino.Geometry.Plane.WorldXY
494 |
495 |
496 | def WorldYZPlane():
497 | """Returns Rhino's world YZ plane
498 | Returns:
499 | plane: Rhino's world YZ plane
500 | Example:
501 | import rhinoscriptsyntax as rs
502 | view = rs.CurrentView()
503 | rs.ViewCPlane( view, rs.WorldYZPlane() )
504 | See Also:
505 | WorldXYPlane
506 | WorldZXPlane
507 | """
508 | return Rhino.Geometry.Plane.WorldYZ
509 |
510 |
511 | def WorldZXPlane():
512 | """Returns Rhino's world ZX plane
513 | Returns:
514 | plane: Rhino's world ZX plane
515 | Example:
516 | import rhinoscriptsyntax as rs
517 | view = rs.CurrentView()
518 | rs.ViewCPlane( view, rs.WorldZXPlane() )
519 | See Also:
520 | WorldXYPlane
521 | WorldYZPlane
522 | """
523 | return Rhino.Geometry.Plane.WorldZX
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/hatch.py:
--------------------------------------------------------------------------------
```python
1 | import System
2 |
3 | import Rhino
4 |
5 | import scriptcontext
6 |
7 | from rhinoscript import utility as rhutil
8 |
9 |
10 | def __initHatchPatterns():
11 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Solid.Name) is None:
12 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Solid)
13 |
14 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Hatch1.Name) is None:
15 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Hatch1)
16 |
17 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Hatch2.Name) is None:
18 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Hatch2)
19 |
20 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Hatch3.Name) is None:
21 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Hatch3)
22 |
23 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Dash.Name) is None:
24 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Dash)
25 |
26 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Grid.Name) is None:
27 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Grid)
28 |
29 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Grid60.Name) is None:
30 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Grid60)
31 |
32 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Plus.Name) is None:
33 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Plus)
34 |
35 | if scriptcontext.doc.HatchPatterns.FindName(Rhino.DocObjects.HatchPattern.Defaults.Squares.Name) is None:
36 | scriptcontext.doc.HatchPatterns.Add(Rhino.DocObjects.HatchPattern.Defaults.Squares)
37 |
38 |
39 | def AddHatch(curve_id, hatch_pattern=None, scale=1.0, rotation=0.0):
40 | """Creates a new hatch object from a closed planar curve object
41 | Parameters:
42 | curve_id (guid): identifier of the closed planar curve that defines the
43 | boundary of the hatch object
44 | hatch_pattern (str, optional): name of the hatch pattern to be used by the hatch
45 | object. If omitted, the current hatch pattern will be used
46 | scale (number, optional): hatch pattern scale factor
47 | rotation (number, optional): hatch pattern rotation angle in degrees.
48 | Returns:
49 | guid:identifier of the newly created hatch on success
50 | None on error
51 | Example:
52 | import rhinoscriptsyntax as rs
53 | circle = rs.AddCircle(rs.WorldXYPlane(), 10.0)
54 | if rs.IsHatchPattern("Grid"):
55 | rs.AddHatch( circle, "Grid" )
56 | else:
57 | rs.AddHatch( circle, rs.CurrentHatchPattern() )
58 | See Also:
59 | AddHatches
60 | CurrentHatchPattern
61 | HatchPatternNames
62 | """
63 | rc = AddHatches(curve_id, hatch_pattern, scale, rotation)
64 | if rc: return rc[0]
65 | return scriptcontext.errorhandler()
66 |
67 |
68 | def AddHatches(curve_ids, hatch_pattern=None, scale=1.0, rotation=0.0, tolerance=None):
69 | """Creates one or more new hatch objects a list of closed planar curves
70 | Parameters:
71 | curve_ids ([guid, ...]): identifiers of the closed planar curves that defines the
72 | boundary of the hatch objects
73 | hatch_pattern (str, optional): name of the hatch pattern to be used by the hatch
74 | object. If omitted, the current hatch pattern will be used
75 | scale (number, optional): hatch pattern scale factor
76 | rotation (number, optional): hatch pattern rotation angle in degrees.
77 | tolerance (number, optional): tolerance for hatch fills.
78 | Returns:
79 | list(guid, ...): identifiers of the newly created hatch on success
80 | None: on error
81 | Example:
82 | import rhinoscriptsyntax as rs
83 | curves = rs.GetObjects("Select closed planar curves", rs.filter.curve)
84 | if curves:
85 | if rs.IsHatchPattern("Grid"):
86 | rs.AddHatches( curves, "Grid" )
87 | else:
88 | rs.AddHatches( curves, rs.CurrentHatchPattern() )
89 | See Also:
90 | AddHatch
91 | CurrentHatchPattern
92 | HatchPatternNames
93 | """
94 | __initHatchPatterns()
95 | id = rhutil.coerceguid(curve_ids, False)
96 | if id: curve_ids = [id]
97 | index = scriptcontext.doc.HatchPatterns.CurrentHatchPatternIndex
98 | if hatch_pattern is None:
99 | hatch_pattern = CurrentHatchPattern()
100 | if isinstance(hatch_pattern, int) and hatch_pattern != index:
101 | index = hatch_pattern
102 | else:
103 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
104 | index = Rhino.RhinoMath.UnsetIntIndex if pattern_instance is None else pattern_instance.Index
105 | if index<0: return scriptcontext.errorhandler()
106 | curves = [rhutil.coercecurve(id, -1, True) for id in curve_ids]
107 | rotation = Rhino.RhinoMath.ToRadians(rotation)
108 | if tolerance is None or tolerance < 0:
109 | tolerance = scriptcontext.doc.ModelAbsoluteTolerance
110 | hatches = Rhino.Geometry.Hatch.Create(curves, index, rotation, scale, tolerance)
111 | if not hatches: return scriptcontext.errorhandler()
112 | ids = []
113 | for hatch in hatches:
114 | id = scriptcontext.doc.Objects.AddHatch(hatch)
115 | if id==System.Guid.Empty: continue
116 | ids.append(id)
117 | if not ids: return scriptcontext.errorhandler()
118 | scriptcontext.doc.Views.Redraw()
119 | return ids
120 |
121 |
122 | def AddHatchPatterns(filename, replace=False):
123 | """Adds hatch patterns to the document by importing hatch pattern definitions
124 | from a pattern file.
125 | Parameters:
126 | filename (str): name of the hatch pattern file
127 | replace (bool, optional): If hatch pattern names already in the document match hatch
128 | pattern names in the pattern definition file, then the existing hatch
129 | patterns will be redefined
130 | Returns:
131 | list(str, ...): Names of the newly added hatch patterns if successful
132 | None: on error
133 | Example:
134 | import rhinoscriptsyntax as rs
135 | filename = rs.OpenFileName("Import", "Pattern Files (*.pat)|*.pat||")
136 | if filename:
137 | patterns = rs.AddHatchPatterns(filename)
138 | if patterns:
139 | for pattern in patterns: print(pattern)
140 | See Also:
141 | HatchPatternCount
142 | HatchPatternNames
143 | """
144 | patterns = Rhino.DocObjects.HatchPattern.ReadFromFile(filename, True)
145 | if not patterns: return scriptcontext.errorhandler()
146 | rc = []
147 | for pattern in patterns:
148 | index = scriptcontext.doc.HatchPatterns.Add(pattern)
149 | if index>=0:
150 | pattern = scriptcontext.doc.HatchPatterns[index]
151 | rc.append(pattern.Name)
152 | if not rc: return scriptcontext.errorhandler()
153 | return rc
154 |
155 |
156 | def CurrentHatchPattern(hatch_pattern=None):
157 | """Returns or sets the current hatch pattern file
158 | Parameters:
159 | hatch_pattern(str, optional): name of an existing hatch pattern to make current
160 | Returns:
161 | str: if hatch_pattern is not specified, the current hatch pattern
162 | str: if hatch_pattern is specified, the previous hatch pattern
163 | None: on error
164 | Example:
165 | import rhinoscriptsyntax as rs
166 | if rs.IsHatchPattern("Hatch2"): rs.CurrentHatchPattern("Hatch2")
167 | See Also:
168 | HatchPatternCount
169 | HatchPatternNames
170 | """
171 | i = scriptcontext.doc.HatchPatterns.CurrentHatchPatternIndex
172 | rc = scriptcontext.doc.HatchPatterns[i].Name
173 | if hatch_pattern:
174 | __initHatchPatterns()
175 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
176 | if pattern_instance is None: return scriptcontext.errorhandler()
177 | scriptcontext.doc.HatchPatterns.CurrentHatchPatternIndex = pattern_instance.Index
178 | return rc
179 |
180 |
181 | def ExplodeHatch(hatch_id, delete=False):
182 | """Explodes a hatch object into its component objects. The exploded objects
183 | will be added to the document. If the hatch object uses a solid pattern,
184 | then planar face Brep objects will be created. Otherwise, line curve objects
185 | will be created
186 | Parameters:
187 | hatch_id (guid): identifier of a hatch object
188 | delete (bool, optional): delete the hatch object
189 | Returns:
190 | list(guid, ...): list of identifiers for the newly created objects
191 | None: on error
192 | Example:
193 | import rhinoscriptsyntax as rs
194 | id = rs.GetObject("Select object")
195 | if rs.IsHatch(id): rs.ExplodeHatch(id, True)
196 | See Also:
197 | IsHatch
198 | HatchPattern
199 | HatchRotation
200 | HatchScale
201 | """
202 | rhobj = rhutil.coercerhinoobject(hatch_id, True, True)
203 | pieces = rhobj.HatchGeometry.Explode()
204 | if not pieces: return scriptcontext.errorhandler()
205 | attr = rhobj.Attributes
206 | rc = []
207 | for piece in pieces:
208 | id = None
209 | if isinstance(piece, Rhino.Geometry.Curve):
210 | id = scriptcontext.doc.Objects.AddCurve(piece, attr)
211 | elif isinstance(piece, Rhino.Geometry.Brep):
212 | id = scriptcontext.doc.Objects.AddBrep(piece, attr)
213 | if id: rc.append(id)
214 | if delete: scriptcontext.doc.Objects.Delete(rhobj)
215 | return rc
216 |
217 |
218 | def HatchPattern(hatch_id, hatch_pattern=None):
219 | """Returns or changes a hatch object's hatch pattern
220 | Parameters:
221 | hatch_id (guid): identifier of a hatch object
222 | hatch_pattern (str, optional): name of an existing hatch pattern to replace the
223 | current hatch pattern
224 | Returns:
225 | str: if hatch_pattern is not specified, the current hatch pattern
226 | str: if hatch_pattern is specified, the previous hatch pattern
227 | None: on error
228 | Example:
229 | import rhinoscriptsyntax as rs
230 | objects = rs.AllObjects()
231 | if objects is not None:
232 | for obj in objects:
233 | if rs.IsHatch(obj) and rs.HatchPattern(obj)=="Solid":
234 | rs.SelectObject(obj)
235 | See Also:
236 | AddHatch
237 | AddHatches
238 | HatchRotation
239 | HatchScale
240 | IsHatch
241 | """
242 | hatchobj = rhutil.coercerhinoobject(hatch_id, True, True)
243 | if not isinstance(hatchobj, Rhino.DocObjects.HatchObject):
244 | return scriptcontext.errorhandler()
245 | old_index = hatchobj.HatchGeometry.PatternIndex
246 | if hatch_pattern:
247 | __initHatchPatterns()
248 | new_patt = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
249 | if new_patt is None: return scriptcontext.errorhandler()
250 | hatchobj.HatchGeometry.PatternIndex = new_patt.Index
251 | hatchobj.CommitChanges()
252 | scriptcontext.doc.Views.Redraw()
253 | return scriptcontext.doc.HatchPatterns[old_index].Name
254 |
255 |
256 | def HatchPatternCount():
257 | """Returns the number of hatch patterns in the document
258 | Returns:
259 | number: the number of hatch patterns in the document
260 | Example:
261 | import rhinoscriptsyntax as rs
262 | print("There are {} hatch patterns.".format(rs.HatchPatternCount()))
263 | See Also:
264 | HatchPatternNames
265 | """
266 | __initHatchPatterns()
267 | return scriptcontext.doc.HatchPatterns.Count
268 |
269 |
270 | def HatchPatternDescription(hatch_pattern):
271 | """Returns the description of a hatch pattern. Note, not all hatch patterns
272 | have descriptions
273 | Parameters:
274 | hatch_pattern (str): name of an existing hatch pattern
275 | Returns:
276 | str: description of the hatch pattern on success otherwise None
277 | Example:
278 | import rhinoscriptsyntax as rs
279 | patterns = rs.HatchPatternNames()
280 | for pattern in patterns:
281 | description = rs.HatchPatternDescription(pattern)
282 | if description: print("{} - {}".format(pattern, description))
283 | else: print(pattern)
284 | See Also:
285 | HatchPatternCount
286 | HatchPatternNames
287 | """
288 | __initHatchPatterns()
289 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
290 | if pattern_instance is None: return scriptcontext.errorhandler()
291 | return pattern_instance.Description
292 |
293 |
294 | def HatchPatternFillType(hatch_pattern):
295 | """Returns the fill type of a hatch pattern.
296 | Parameters:
297 | hatch_pattern (str): name of an existing hatch pattern
298 | Returns:
299 | number: hatch pattern's fill type if successful
300 | 0 = solid, uses object color
301 | 1 = lines, uses pattern file definition
302 | 2 = gradient, uses fill color definition
303 | None: if unsuccessful
304 | Example:
305 | import rhinoscriptsyntax as rs
306 | patterns = rs.HatchPatternNames()
307 | for pattern in patterns:
308 | fill = rs.HatchPatternFillType(pattern)
309 | print("{} - {}".format(pattern, fill))
310 | See Also:
311 | HatchPatternCount
312 | HatchPatternNames
313 | """
314 | __initHatchPatterns()
315 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
316 | if pattern_instance is None: return scriptcontext.errorhandler()
317 | return int(pattern_instance.FillType)
318 |
319 |
320 | def HatchPatternNames():
321 | """Returns the names of all of the hatch patterns in the document
322 | Returns:
323 | list(str, ...): the names of all of the hatch patterns in the document
324 | Example:
325 | import rhinoscriptsyntax as rs
326 | patterns = rs.HatchPatternNames()
327 | for pattern in patterns:
328 | description = rs.HatchPatternDescription(pattern)
329 | if description: print("{} - {}".format(pattern, description))
330 | else: print(pattern)
331 | See Also:
332 | HatchPatternCount
333 | """
334 | __initHatchPatterns()
335 | rc = []
336 | for i in range(scriptcontext.doc.HatchPatterns.Count):
337 | hatchpattern = scriptcontext.doc.HatchPatterns[i]
338 | if hatchpattern.IsDeleted: continue
339 | rc.append(hatchpattern.Name)
340 | return rc
341 |
342 |
343 | def HatchRotation(hatch_id, rotation=None):
344 | """Returns or modifies the rotation applied to the hatch pattern when
345 | it is mapped to the hatch's plane
346 | Parameters:
347 | hatch_id (guid): identifier of a hatch object
348 | rotation (number, optional): rotation angle in degrees
349 | Returns:
350 | number: if rotation is not defined, the current rotation angle
351 | number: if rotation is specified, the previous rotation angle
352 | None: on error
353 | Example:
354 | import rhinoscriptsyntax as rs
355 | objects = rs.AllObjects()
356 | if objects:
357 | for obj in objects:
358 | if rs.IsHatch(obj) and rs.HatchRotation(obj)>0:
359 | rs.HatchRotation(obj,0)
360 | See Also:
361 | AddHatch
362 | AddHatches
363 | HatchPattern
364 | HatchScale
365 | IsHatch
366 | """
367 | hatchobj = rhutil.coercerhinoobject(hatch_id, True, True)
368 | if not isinstance(hatchobj, Rhino.DocObjects.HatchObject):
369 | return scriptcontext.errorhandler()
370 | rc = hatchobj.HatchGeometry.PatternRotation
371 | rc = Rhino.RhinoMath.ToDegrees(rc)
372 | if rotation is not None and rotation!=rc:
373 | rotation = Rhino.RhinoMath.ToRadians(rotation)
374 | hatchobj.HatchGeometry.PatternRotation = rotation
375 | hatchobj.CommitChanges()
376 | scriptcontext.doc.Views.Redraw()
377 | return rc
378 |
379 |
380 | def HatchScale(hatch_id, scale=None):
381 | """Returns or modifies the scale applied to the hatch pattern when it is
382 | mapped to the hatch's plane
383 | Parameters:
384 | hatch_id (guid): identifier of a hatch object
385 | scale (number, optional): scale factor
386 | Returns:
387 | number: if scale is not defined, the current scale factor
388 | number: if scale is defined, the previous scale factor
389 | None: on error
390 | Example:
391 | import rhinoscriptsyntax as rs
392 | objects = rs.NormalObjects()
393 | if objects:
394 | for obj in objects:
395 | if rs.IsHatch(obj) and rs.HatchScale(obj)>1.0:
396 | rs.HatchScale(obj, 1.0)
397 | See Also:
398 | HatchPattern
399 | HatchRotation
400 | IsHatch
401 | """
402 | hatchobj = rhutil.coercerhinoobject(hatch_id)
403 | if not isinstance(hatchobj, Rhino.DocObjects.HatchObject):
404 | return scriptcontext.errorhandler()
405 | rc = hatchobj.HatchGeometry.PatternScale
406 | if scale and scale!=rc:
407 | hatchobj.HatchGeometry.PatternScale = scale
408 | hatchobj.CommitChanges()
409 | scriptcontext.doc.Views.Redraw()
410 | return rc
411 |
412 |
413 | def IsHatch(object_id):
414 | """Verifies the existence of a hatch object in the document
415 | Parameters:
416 | object_id (guid): identifier of an object
417 | Returns:
418 | bool: True or False
419 | Example:
420 | import rhinoscriptsyntax as rs
421 | obj = rs.GetObject("Select object")
422 | if rs.IsHatch(obj): print("Object is a hatch")
423 | else: print("Object is not a hatch")
424 | See Also:
425 | HatchPattern
426 | HatchRotation
427 | HatchScale
428 | """
429 | rhobj = rhutil.coercerhinoobject(object_id, True, False)
430 | return isinstance(rhobj, Rhino.DocObjects.HatchObject)
431 |
432 |
433 | def IsHatchPattern(name):
434 | """Verifies the existence of a hatch pattern in the document
435 | Parameters:
436 | name (str): the name of a hatch pattern
437 | Returns:
438 | bool: True or False
439 | Example:
440 | import rhinoscriptsyntax as rs
441 | hatch = rs.GetString("Hatch pattern name")
442 | if rs.IsHatchPattern(hatch): print("The hatch pattern exists.")
443 | else: print("The hatch pattern does not exist.")
444 | See Also:
445 | IsHatchPatternCurrent
446 | IsHatchPatternReference
447 | """
448 | __initHatchPatterns()
449 | return scriptcontext.doc.HatchPatterns.FindName(name) is not None
450 |
451 |
452 | def IsHatchPatternCurrent(hatch_pattern):
453 | """Verifies that a hatch pattern is the current hatch pattern
454 | Parameters:
455 | hatch_pattern (str): name of an existing hatch pattern
456 | Returns:
457 | bool: True or False
458 | None: on error
459 | Example:
460 | import rhinoscriptsyntax as rs
461 | hatch = rs.GetString("Hatch pattern name")
462 | if rs.IsHatchPattern(hatch):
463 | if rs.IsHatchPatternCurrent(hatch):
464 | print("The hatch pattern is current.")
465 | else:
466 | print("The hatch pattern is not current.")
467 | else: print("The hatch pattern does not exist.")
468 | See Also:
469 | IsHatchPattern
470 | IsHatchPatternReference
471 | """
472 | __initHatchPatterns()
473 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
474 | if pattern_instance is None: return scriptcontext.errorhandler()
475 | return pattern_instance.Index==scriptcontext.doc.HatchPatterns.CurrentHatchPatternIndex
476 |
477 |
478 | def IsHatchPatternReference(hatch_pattern):
479 | """Verifies that a hatch pattern is from a reference file
480 | Parameters:
481 | hatch_pattern (str): name of an existing hatch pattern
482 | Returns:
483 | bool: True or False
484 | None: on error
485 | Example:
486 | import rhinoscriptsyntax as rs
487 | hatch = rs.GetString("Hatch pattern name")
488 | if rs.IsHatchPattern(hatch):
489 | if rs.IsHatchPatternReference(hatch):
490 | print("The hatch pattern is reference.")
491 | else:
492 | print("The hatch pattern is not reference.")
493 | else:
494 | print("The hatch pattern does not exist.")
495 | See Also:
496 | IsHatchPattern
497 | IsHatchPatternCurrent
498 | """
499 | __initHatchPatterns()
500 | pattern_instance = scriptcontext.doc.HatchPatterns.FindName(hatch_pattern)
501 | if pattern_instance is None: return scriptcontext.errorhandler()
502 | return pattern_instance.IsReference
503 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/transformation.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import Rhino
4 |
5 | import scriptcontext
6 |
7 | from rhinoscript import utility as rhutil
8 | from rhinoscript.view import __viewhelper
9 |
10 |
11 | def IsXformIdentity(xform):
12 | """Verifies a matrix is the identity matrix
13 | Parameters:
14 | xform (transform): List or Rhino.Geometry.Transform. A 4x4 transformation matrix.
15 | Returns:
16 | bool: True or False indicating success or failure.
17 | Example:
18 | import rhinoscriptsyntax as rs
19 | xform = rs.XformIdentity()
20 | print(rs.IsXformIdentity(xform))
21 | See Also:
22 | IsXformSimilarity
23 | IsXformZero
24 | XformIdentity
25 | """
26 | xform = rhutil.coercexform(xform, True)
27 | return xform==Rhino.Geometry.Transform.Identity
28 |
29 |
30 | def IsXformSimilarity(xform):
31 | """Verifies a matrix is a similarity transformation. A similarity
32 | transformation can be broken into a sequence of dilations, translations,
33 | rotations, and reflections
34 | Parameters:
35 | xform (transform): List or Rhino.Geometry.Transform. A 4x4 transformation matrix.
36 | Returns:
37 | bool: True if this transformation is an orientation preserving similarity, otherwise False.
38 | Example:
39 | import rhinoscriptsyntax as rs
40 | xform = rs.BlockInstanceXform(block)
41 | print(rs.IsXformSimilarity(xform))
42 | See Also:
43 | IsXformIdentity
44 | IsXformZero
45 | """
46 | xform = rhutil.coercexform(xform, True)
47 | return xform.SimilarityType!=Rhino.Geometry.TransformSimilarityType.NotSimilarity
48 |
49 |
50 | def IsXformZero(xform):
51 | """verifies that a matrix is a zero transformation matrix
52 | Parameters:
53 | xform (transform): List or Rhino.Geometry.Transform. A 4x4 transformation matrix.
54 | Returns:
55 | bool: True or False indicating success or failure.
56 | Example:
57 | import rhinoscriptsyntax as rs
58 | xform = rs.XformZero()
59 | print(rs.IsXformZero(xform))
60 | See Also:
61 | IsXformIdentity
62 | IsXformSimilarity
63 | XformZero
64 | """
65 | xform = rhutil.coercexform(xform, True)
66 | for i in range(4):
67 | for j in range(4):
68 | if xform[i,j]!=0: return False
69 | return True
70 |
71 |
72 | def XformChangeBasis(initial_plane, final_plane):
73 | """Returns a change of basis transformation matrix or None on error
74 | Parameters:
75 | initial_plane (plane): the initial plane
76 | final_plane (plane): the final plane
77 | Returns:
78 | transform: The 4x4 transformation matrix if successful
79 | None: if not successful
80 | Example:
81 | import rhinoscriptsyntax as rs
82 | import math
83 | objs = rs.GetObjects("Select objects to shear")
84 | if objs:
85 | cplane = rs.ViewCPlane()
86 | cob = rs.XformChangeBasis(rs.WorldXYPlane(), cplane)
87 | shear2d = rs.XformIdentity()
88 | shear2d[0,2] = math.tan(math.radians(45.0))
89 | cob_inverse = rs.XformChangeBasis(cplane, rs.WorldXYPlane())
90 | temp = rs.XformMultiply(shear2d, cob)
91 | xform = rs.XformMultiply(cob_inverse, temp)
92 | rs.TransformObjects( objs, xform, True )
93 | See Also:
94 | XformCPlaneToWorld
95 | XformWorldToCPlane
96 | """
97 | initial_plane = rhutil.coerceplane(initial_plane, True)
98 | final_plane = rhutil.coerceplane(final_plane, True)
99 | xform = Rhino.Geometry.Transform.ChangeBasis(initial_plane, final_plane)
100 | if not xform.IsValid: return scriptcontext.errorhandler()
101 | return xform
102 |
103 |
104 | def XformChangeBasis2(x0,y0,z0,x1,y1,z1):
105 | """Returns a change of basis transformation matrix of None on error
106 | Parameters:
107 | x0,y0,z0 (vector): initial basis
108 | x1,y1,z1 (vector): final basis
109 | Returns:
110 | transform: The 4x4 transformation matrix if successful
111 | None: if not successful
112 | Example:
113 | See Also:
114 | """
115 | x0 = rhutil.coerce3dvector(x0, True)
116 | y0 = rhutil.coerce3dvector(y0, True)
117 | z0 = rhutil.coerce3dvector(z0, True)
118 | x1 = rhutil.coerce3dvector(x1, True)
119 | y1 = rhutil.coerce3dvector(y1, True)
120 | z1 = rhutil.coerce3dvector(z1, True)
121 | xform = Rhino.Geometry.Transform.ChangeBasis(x0,y0,z0,x1,y1,z1)
122 | if not xform.IsValid: return scriptcontext.errorhandler()
123 | return xform
124 |
125 |
126 | def XformCompare(xform1, xform2):
127 | """Compares two transformation matrices
128 | Parameters:
129 | xform1, xform2 = matrices to compare
130 | Returns:
131 | number:
132 | -1 if xform1<xform2
133 | 1 if xform1>xform2
134 | 0 if xform1=xform2
135 | Example:
136 | import rhinoscriptsyntax as rs
137 | xform0 = rs.XformZero()
138 | xform1 = rs.XformIdentity()
139 | print(rs.XformCompare(xform0, xform1))
140 | See Also:
141 | IsXformIdentity
142 | IsXformSimilarity
143 | IsXformZero
144 | """
145 | xform1 = rhutil.coercexform(xform1, True)
146 | xform2 = rhutil.coercexform(xform2, True)
147 | return xform1.CompareTo(xform2)
148 |
149 |
150 | def XformCPlaneToWorld(point, plane):
151 | """Transform point from construction plane coordinates to world coordinates
152 | Parameters:
153 | point (point): A 3D point in construction plane coordinates.
154 | plane (plane): The construction plane
155 | Returns:
156 | point: A 3D point in world coordinates
157 | Example:
158 | import rhinoscriptsyntax as rs
159 | plane = rs.ViewCPlane()
160 | point = rs.XFormCPlaneToWorld([0,0,0], plane)
161 | if point: print("World point: {}".format(point))
162 | See Also:
163 | XformWorldToCPlane
164 | """
165 | point = rhutil.coerce3dpoint(point, True)
166 | plane = rhutil.coerceplane(plane, True)
167 | return plane.Origin + point.X*plane.XAxis + point.Y*plane.YAxis + point.Z*plane.ZAxis
168 |
169 |
170 | def XformDeterminant(xform):
171 | """Returns the determinant of a transformation matrix. If the determinant
172 | of a transformation matrix is 0, the matrix is said to be singular. Singular
173 | matrices do not have inverses.
174 | Parameters:
175 | xform (transform): List or Rhino.Geometry.Transform. A 4x4 transformation matrix.
176 | Returns:
177 | number: The determinant if successful
178 | None: if not successful
179 | Example:
180 | import rhinoscriptsyntax as rs
181 | xform = rs.BlockInstanceXform(obj)
182 | if xform: print(rs.XformDeterminant(xform))
183 | See Also:
184 | XformInverse
185 | """
186 | xform = rhutil.coercexform(xform, True)
187 | return xform.Determinant
188 |
189 |
190 | def XformDiagonal(diagonal_value):
191 | """Returns a diagonal transformation matrix. Diagonal matrices are 3x3 with
192 | the bottom row [0,0,0,1]
193 | Parameters:
194 | diagonal_value (number): the diagonal value
195 | Returns:
196 | transform: The 4x4 transformation matrix if successful
197 | None: if not successful
198 | Example:
199 | import rhinoscriptsyntax as rs
200 | def printmatrix(xform):
201 | for i in range(4):
202 | print("[{}, {}, {}, {}]".format(xform[i,0], xform[i,1], xform[i,2], xform[i,3]))
203 | printmatrix(rs.XformDiagonal(3))
204 | See Also:
205 | XformIdentity
206 | XformZero
207 | """
208 | return Rhino.Geometry.Transform(diagonal_value)
209 |
210 |
211 | def XformIdentity():
212 | """returns the identity transformation matrix
213 | Returns:
214 | transform: The 4x4 transformation matrix
215 | Example:
216 | import rhinoscriptsyntax as rs
217 | def printmatrix(xform):
218 | for i in range(4):
219 | print("[{}, {}, {}, {}]".format(xform[i,0], xform[i,1], xform[i,2], xform[i,3]))
220 | printmatrix(rs.XformIdentity())
221 | See Also:
222 | XformDiagonal
223 | XformZero
224 | """
225 | return Rhino.Geometry.Transform.Identity
226 |
227 |
228 | def XformInverse(xform):
229 | """Returns the inverse of a non-singular transformation matrix
230 | Parameters:
231 | xform (transform): List or Rhino.Geometry.Transform. A 4x4 transformation matrix.
232 | Returns:
233 | transform: The inverted 4x4 transformation matrix if successful.
234 | None: if matrix is non-singular or on error.
235 | Example:
236 | import rhinoscriptsyntax as rs
237 | xform = rs.BlockInstanceXform(obj)
238 | if xform:
239 | rs.TransformObject( obj, rs.XformInverse(xform) )
240 | See Also:
241 | XformDeterminant
242 | """
243 | xform = rhutil.coercexform(xform, True)
244 | rc, inverse = xform.TryGetInverse()
245 | if not rc: return scriptcontext.errorhandler()
246 | return inverse
247 |
248 |
249 | def XformMirror(mirror_plane_point, mirror_plane_normal):
250 | """Creates a mirror transformation matrix
251 | Parameters:
252 | mirror_plane_point (point): point on the mirror plane
253 | mirror_plane_normal (vector): a 3D vector that is normal to the mirror plane
254 | Returns:
255 | transform: mirror Transform matrix
256 | Example:
257 | import rhinoscriptsyntax as rs
258 | objs = rs.GetObjects("Select objects to mirror")
259 | if objs:
260 | plane = rs.ViewCPlane()
261 | xform = rs.XformMirror(plane.Origin, plane.Normal)
262 | rs.TransformObjects( objs, xform, True )
263 | See Also:
264 | XformPlanarProjection
265 | XformRotation1
266 | XformRotation2
267 | XformRotation3
268 | XformRotation4
269 | XformScale
270 | XformShear
271 | XformTranslation
272 | """
273 | point = rhutil.coerce3dpoint(mirror_plane_point, True)
274 | normal = rhutil.coerce3dvector(mirror_plane_normal, True)
275 | return Rhino.Geometry.Transform.Mirror(point, normal)
276 |
277 |
278 | def XformMultiply(xform1, xform2):
279 | """Multiplies two transformation matrices, where result = xform1 * xform2
280 | Parameters:
281 | xform1 (transform): List or Rhino.Geometry.Transform. The first 4x4 transformation matrix to multiply.
282 | xform2 (transform): List or Rhino.Geometry.Transform. The second 4x4 transformation matrix to multiply.
283 | Returns:
284 | transform: result transformation on success
285 | Example:
286 | import rhinoscriptsyntax as rs
287 | import math
288 | objs = rs.GetObjects("Select objects to shear")
289 | if objs:
290 | cplane = rs.ViewCPlane()
291 | cob = rs.XformChangeBasis(rs.WorldXYPlane(), cplane)
292 | shear2d = rs.XformIdentity()
293 | shear2d[0,2] = math.tan(math.radians(45.0))
294 | cob_inv = rs.XformChangeBasis(cplane, rs.WorldXYPlane())
295 | temp = rs.XformMultiply(shear2d, cob)
296 | xform = rs.XformMultiply(cob_inv, temp)
297 | rs.TransformObjects( objs, xform, True )
298 | See Also:
299 | XformPlanarProjection
300 | XformRotation1
301 | XformRotation2
302 | XformRotation3
303 | XformRotation4
304 | XformScale
305 | XformShear
306 | XformTranslation
307 | """
308 | xform1 = rhutil.coercexform(xform1, True)
309 | xform2 = rhutil.coercexform(xform2, True)
310 | return xform1*xform2
311 |
312 |
313 | def XformPlanarProjection(plane):
314 | """Returns a transformation matrix that projects to a plane.
315 | Parameters:
316 | plane (plane): The plane to project to.
317 | Returns:
318 | transform: The 4x4 transformation matrix.
319 | Example:
320 | import rhinoscriptsyntax as rs
321 | objects = rs.GetObjects("Select objects to project")
322 | if objects:
323 | cplane = rs.ViewCPlane()
324 | xform = rs.XformPlanarProjection(cplane)
325 | rs.TransformObjects( objects, xform, True )
326 | See Also:
327 | XformMirror
328 | XformRotation1
329 | XformRotation2
330 | XformRotation3
331 | XformRotation4
332 | XformScale
333 | XformShear
334 | XformTranslation
335 | """
336 | plane = rhutil.coerceplane(plane, True)
337 | return Rhino.Geometry.Transform.PlanarProjection(plane)
338 |
339 |
340 | def XformRotation1(initial_plane, final_plane):
341 | """Returns a rotation transformation that maps initial_plane to final_plane.
342 | The planes should be right hand orthonormal planes.
343 | Parameters:
344 | initial_plane (plane): plane to rotate from
345 | final_plane (plane): plane to rotate to
346 | Returns:
347 | transform: The 4x4 transformation matrix.
348 | None: on error.
349 | Example:
350 | See Also:
351 | """
352 | initial_plane = rhutil.coerceplane(initial_plane, True)
353 | final_plane = rhutil.coerceplane(final_plane, True)
354 | xform = Rhino.Geometry.Transform.PlaneToPlane(initial_plane, final_plane)
355 | if not xform.IsValid: return scriptcontext.errorhandler()
356 | return xform
357 |
358 |
359 | def XformRotation2(angle_degrees, rotation_axis, center_point):
360 | """Returns a rotation transformation around an axis
361 | Parameters:
362 | angle_degrees (number): rotation angle in degrees
363 | rotation_axis (vector): rotation axis
364 | center_point (point): rotation center
365 | Returns:
366 | transform: The 4x4 transformation matrix.
367 | None: on error.
368 | Example:
369 | See Also:
370 | """
371 | axis = rhutil.coerce3dvector(rotation_axis, True)
372 | center = rhutil.coerce3dpoint(center_point, True)
373 | angle_rad = math.radians(angle_degrees)
374 | xform = Rhino.Geometry.Transform.Rotation(angle_rad, axis, center)
375 | if not xform.IsValid: return scriptcontext.errorhandler()
376 | return xform
377 |
378 |
379 | def XformRotation3( start_direction, end_direction, center_point ):
380 | """Calculate the minimal transformation that rotates start_direction to
381 | end_direction while fixing center_point
382 | Parameters:
383 | start_direction, end_direction (vector): 3d vectors
384 | center_point (point): the rotation center
385 | Returns:
386 | transform: The 4x4 transformation matrix.
387 | None: on error.
388 | Example:
389 | See Also:
390 | """
391 | start = rhutil.coerce3dvector(start_direction, True)
392 | end = rhutil.coerce3dvector(end_direction, True)
393 | center = rhutil.coerce3dpoint(center_point, True)
394 | xform = Rhino.Geometry.Transform.Rotation(start, end, center)
395 | if not xform.IsValid: return scriptcontext.errorhandler()
396 | return xform
397 |
398 |
399 | def XformRotation4(x0, y0, z0, x1, y1, z1):
400 | """Returns a rotation transformation.
401 | Parameters:
402 | x0,y0,z0 (vector): Vectors defining the initial orthonormal frame
403 | x1,y1,z1 (vector): Vectors defining the final orthonormal frame
404 | Returns:
405 | transform: The 4x4 transformation matrix.
406 | None: on error.
407 | Example:
408 | See Also:
409 | """
410 | x0 = rhutil.coerce3dvector(x0, True)
411 | y0 = rhutil.coerce3dvector(y0, True)
412 | z0 = rhutil.coerce3dvector(z0, True)
413 | x1 = rhutil.coerce3dvector(x1, True)
414 | y1 = rhutil.coerce3dvector(y1, True)
415 | z1 = rhutil.coerce3dvector(z1, True)
416 | xform = Rhino.Geometry.Transform.Rotation(x0,y0,z0,x1,y1,z1)
417 | if not xform.IsValid: return scriptcontext.errorhandler()
418 | return xform
419 |
420 |
421 | def XformScale(scale, point=None):
422 | """Creates a scale transformation
423 | Parameters:
424 | scale (number|point|vector|[number, number, number]): single number, list of 3 numbers, Point3d, or Vector3d
425 | point (point, optional): center of scale. If omitted, world origin is used
426 | Returns:
427 | transform: The 4x4 transformation matrix on success
428 | None: on error
429 | Example:
430 | import rhinoscriptsyntax as rs
431 | objs = rs.GetObjects("Select objects to scale")
432 | if objs:
433 | xform = rs.XformScale( (3.0,1.0,1.0) )
434 | rs.TransformObjects( objs, xform, True)
435 | See Also:
436 | XformMirror
437 | XformPlanarProjection
438 | XformRotation1
439 | XformRotation2
440 | XformRotation3
441 | XformRotation4
442 | XformShear
443 | XformTranslation
444 | """
445 | factor = rhutil.coerce3dpoint(scale)
446 | if factor is None:
447 | if type(scale) is int or type(scale) is float:
448 | factor = (scale,scale,scale)
449 | if factor is None: return scriptcontext.errorhandler()
450 | if point: point = rhutil.coerce3dpoint(point, True)
451 | else: point = Rhino.Geometry.Point3d.Origin
452 | plane = Rhino.Geometry.Plane(point, Rhino.Geometry.Vector3d.ZAxis);
453 | xf = Rhino.Geometry.Transform.Scale(plane, factor[0], factor[1], factor[2])
454 | return xf
455 |
456 |
457 | def XformScreenToWorld(point, view=None, screen_coordinates=False):
458 | """Transforms a point from either client-area coordinates of the specified view
459 | or screen coordinates to world coordinates. The resulting coordinates are represented
460 | as a 3-D point
461 | Parameters:
462 | point (point): 2D point
463 | view (str, optional): title or identifier of a view. If omitted, the active view is used
464 | screen_coordinates (bool, optional): if False, point is in client-area coordinates. If True,
465 | point is in screen-area coordinates
466 | Returns:
467 | point: on success
468 | None: on error
469 | Example:
470 | import rhinoscriptsyntax as rs
471 | point2d = 200,100
472 | view = rs.CurrentView()
473 | point = rs.XformScreenToWorld(point2d, view)
474 | print(point)
475 | See Also:
476 | XformWorldToScreen
477 | """
478 | point = rhutil.coerce2dpoint(point, True)
479 | view = __viewhelper(view)
480 | viewport = view.MainViewport
481 | xform = viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.Screen, Rhino.DocObjects.CoordinateSystem.World)
482 | point3d = Rhino.Geometry.Point3d(point.X, point.Y, 0)
483 | if screen_coordinates:
484 | screen = view.ScreenRectangle
485 | point3d.X = point.X - screen.Left
486 | point3d.Y = point.Y - screen.Top
487 | point3d = xform * point3d
488 | return point3d
489 |
490 |
491 | def XformShear(plane, x, y, z):
492 | """Returns a shear transformation matrix
493 | Parameters:
494 | plane (plane): plane[0] is the fixed point
495 | x,y,z (number): each axis scale factor
496 | Returns:
497 | transform: The 4x4 transformation matrix on success
498 | Example:
499 | import rhinoscriptsyntax as rs
500 | objects = rs.GetObjects("Select objects to shear")
501 | if objects:
502 | cplane = rs.ViewCPlane()
503 | xform = rs.XformShear(cplane, (1,1,0), (-1,1,0), (0,0,1))
504 | rs.TransformObjects(objects, xform, True)
505 | See Also:
506 | XformMirror
507 | XformPlanarProjection
508 | XformRotation1
509 | XformRotation2
510 | XformRotation3
511 | XformRotation4
512 | XformScale
513 | XformTranslation
514 | """
515 | plane = rhutil.coerceplane(plane, True)
516 | x = rhutil.coerce3dvector(x, True)
517 | y = rhutil.coerce3dvector(y, True)
518 | z = rhutil.coerce3dvector(z, True)
519 | return Rhino.Geometry.Transform.Shear(plane,x,y,z)
520 |
521 |
522 | def XformTranslation(vector):
523 | """Creates a translation transformation matrix
524 | Parameters:
525 | vector (vector): List of 3 numbers, Point3d, or Vector3d. A 3-D translation vector.
526 | Returns:
527 | transform: The 4x4 transformation matrix is successful, otherwise None
528 | Example:
529 | import rhinoscriptsyntax as rs
530 | objs = rs.GetObjects("Select objects to copy")
531 | if objs:
532 | xform = rs.XformTranslation([1,0,0])
533 | rs.TransformObjects( objs, xform, True )
534 | See Also:
535 | XformMirror
536 | XformPlanarProjection
537 | XformRotation1
538 | XformRotation2
539 | XformRotation3
540 | XformRotation4
541 | XformScale
542 | XformShear
543 | """
544 | vector = rhutil.coerce3dvector(vector, True)
545 | return Rhino.Geometry.Transform.Translation(vector)
546 |
547 |
548 | def XformWorldToCPlane(point, plane):
549 | """Transforms a point from world coordinates to construction plane coordinates.
550 | Parameters:
551 | point (point): A 3D point in world coordinates.
552 | plane (plane): The construction plane
553 | Returns:
554 | (point): 3D point in construction plane coordinates
555 | Example:
556 | import rhinoscriptsyntax as rs
557 | plane = rs.ViewCPlane()
558 | point = rs.XformWorldToCPlane([0,0,0], plane)
559 | if point: print("CPlane point:{}".format(point))
560 | See Also:
561 | XformCPlaneToWorld
562 | """
563 | point = rhutil.coerce3dpoint(point, True)
564 | plane = rhutil.coerceplane(plane, True)
565 | v = point - plane.Origin;
566 | return Rhino.Geometry.Point3d(v*plane.XAxis, v*plane.YAxis, v*plane.ZAxis)
567 |
568 |
569 | def XformWorldToScreen(point, view=None, screen_coordinates=False):
570 | """Transforms a point from world coordinates to either client-area coordinates of
571 | the specified view or screen coordinates. The resulting coordinates are represented
572 | as a 2D point
573 | Parameters:
574 | point (point): 3D point in world coordinates
575 | view (str, optional): title or identifier of a view. If omitted, the active view is used
576 | screen_coordinates (bool, optional): if False, the function returns the results as
577 | client-area coordinates. If True, the result is in screen-area coordinates
578 | Returns:
579 | (point): 2D point on success
580 | None: on error
581 | Example:
582 | import rhinoscriptsyntax as rs
583 | point = (0.0, 0.0, 0.0)
584 | view = rs.CurrentView()
585 | point2d = rs.XformWorldToScreen(point, view)
586 | print(point2d)
587 | See Also:
588 | XformScreenToWorld
589 | """
590 | point = rhutil.coerce3dpoint(point, True)
591 | view = __viewhelper(view)
592 | viewport = view.MainViewport
593 | xform = viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.World, Rhino.DocObjects.CoordinateSystem.Screen)
594 | point = xform * point
595 | point = Rhino.Geometry.Point2d(point.X, point.Y)
596 | if screen_coordinates:
597 | screen = view.ScreenRectangle
598 | point.X = point.X + screen.Left
599 | point.Y = point.Y + screen.Top
600 | return point
601 |
602 |
603 | def XformZero():
604 | """Returns a zero transformation matrix
605 | Returns:
606 | transform: a zero transformation matrix
607 | Example:
608 | import rhinoscriptsyntax as rs
609 | def printmatrix(xform):
610 | for i in range(4):
611 | print("[{}, {}, {}, {}]".format(xform[i,0], xform[i,1], xform[i,2], xform[i,3]))
612 | printmatrix( rs.XformZero() )
613 | See Also:
614 | XformDiagonal
615 | XformIdentity
616 | """
617 | return Rhino.Geometry.Transform()
618 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/light.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import Rhino.Geometry
4 |
5 | import scriptcontext
6 |
7 | import rhinocompat as compat
8 | from rhinoscript import utility as rhutil
9 |
10 |
11 | def __coercelight(id, raise_if_missing=False):
12 | light = rhutil.coercegeometry(id)
13 | if isinstance(light, Rhino.Geometry.Light): return light
14 | if raise_if_missing: raise ValueError("unable to retrieve light from %s"%id)
15 |
16 |
17 | def AddDirectionalLight(start_point, end_point):
18 | """Adds a new directional light object to the document
19 | Parameters:
20 | start_point(point): starting point of the light
21 | end_point (point): ending point and direction of the light
22 | Returns:
23 | (guid): identifier of the new object if successful
24 | Example:
25 | import rhinoscriptsyntax as rs
26 | end = rs.GetPoint("End of light vector direction")
27 | if end:
28 | start = rs.GetPoint("Start of light vector direction", end)
29 | if start: rs.AddDirectionalLight( start, end )
30 | See Also:
31 | IsDirectionalLight
32 | """
33 | start = rhutil.coerce3dpoint(start_point, True)
34 | end = rhutil.coerce3dpoint(end_point, True)
35 | light = Rhino.Geometry.Light()
36 | light.LightStyle = Rhino.Geometry.LightStyle.WorldDirectional
37 | light.Location = start
38 | light.Direction = end-start
39 | index = scriptcontext.doc.Lights.Add(light)
40 | if index<0: raise Exception("unable to add light to LightTable")
41 | rc = scriptcontext.doc.Lights[index].Id
42 | scriptcontext.doc.Views.Redraw()
43 | return rc
44 |
45 |
46 | def AddLinearLight(start_point, end_point, width=None):
47 | """Adds a new linear light object to the document
48 | Parameters:
49 | start_point (point): starting point of the light
50 | end_point (point): ending point and direction of the light
51 | width (number): width of the light
52 | Returns:
53 | guid: identifier of the new object if successful
54 | None: on error
55 | Example:
56 | import rhinoscriptsyntax as rs
57 | start = rs.GetPoint("Light origin")
58 | if start:
59 | end = rs.GetPoint("Light length and direction", start)
60 | if end: rs.AddLinearLight(start, end)
61 | See Also:
62 | IsLinearLight
63 | """
64 | start = rhutil.coerce3dpoint(start_point, True)
65 | end = rhutil.coerce3dpoint(end_point, True)
66 | if width is None:
67 | radius=0.5
68 | units = scriptcontext.doc.ModelUnitSystem
69 | if units!=compat.ENUM_NONE(Rhino.UnitSystem):
70 | scale = Rhino.RhinoMath.UnitScale(Rhino.UnitSystem.Inches, units)
71 | radius *= scale
72 | width = radius
73 | light = Rhino.Geometry.Light()
74 | light.LightStyle = Rhino.Geometry.LightStyle.WorldLinear
75 | light.Location = start
76 | v = end-start
77 | light.Direction = v
78 | light.Length = light.Direction
79 | light.Width = -light.Width
80 | plane = Rhino.Geometry.Plane(light.Location, light.Direction)
81 | xaxis = plane.XAxis
82 | xaxis.Unitize()
83 | plane.XAxis = xaxis
84 | light.Width = xaxis * min(width, v.Length/20)
85 | #light.Location = start - light.Direction
86 | index = scriptcontext.doc.Lights.Add(light)
87 | if index<0: raise Exception("unable to add light to LightTable")
88 | rc = scriptcontext.doc.Lights[index].Id
89 | scriptcontext.doc.Views.Redraw()
90 | return rc
91 |
92 |
93 | def AddPointLight(point):
94 | """Adds a new point light object to the document
95 | Parameters:
96 | point (point): the 3d location of the point
97 | Returns:
98 | guid: identifier of the new object if successful
99 | Example:
100 | import rhinoscriptsyntax as rs
101 | point = rs.GetPoint("Point light location")
102 | if point: rs.AddPointLight(point)
103 | See Also:
104 | IsPointLight
105 | """
106 | point = rhutil.coerce3dpoint(point, True)
107 | light = Rhino.Geometry.Light()
108 | light.LightStyle = Rhino.Geometry.LightStyle.WorldPoint
109 | light.Location = point
110 | index = scriptcontext.doc.Lights.Add(light)
111 | if index<0: raise Exception("unable to add light to LightTable")
112 | rc = scriptcontext.doc.Lights[index].Id
113 | scriptcontext.doc.Views.Redraw()
114 | return rc
115 |
116 |
117 | def AddRectangularLight(origin, width_point, height_point):
118 | """Adds a new rectangular light object to the document
119 | Parameters:
120 | origin (point): 3d origin point of the light
121 | width_point (point): 3d width and direction point of the light
122 | height_point (point): 3d height and direction point of the light
123 | Returns:
124 | guid: identifier of the new object if successful
125 | Example:
126 | import rhinoscriptsyntax as rs
127 | rect = rs.GetRectangle(2)
128 | if rect: rs.AddRectangularLight( rect[0], rect[1], rect[3] )
129 | See Also:
130 | IsRectangularLight
131 | """
132 | origin = rhutil.coerce3dpoint(origin, True)
133 | ptx = rhutil.coerce3dpoint(width_point, True)
134 | pty = rhutil.coerce3dpoint(height_point, True)
135 | length = pty-origin
136 | width = ptx-origin
137 | normal = Rhino.Geometry.Vector3d.CrossProduct(width, length)
138 | normal.Unitize()
139 | light = Rhino.Geometry.Light()
140 | light.LightStyle = Rhino.Geometry.LightStyle.WorldRectangular
141 | light.Location = origin
142 | light.Width = width
143 | light.Length = length
144 | light.Direction = normal
145 | index = scriptcontext.doc.Lights.Add(light)
146 | if index<0: raise Exception("unable to add light to LightTable")
147 | rc = scriptcontext.doc.Lights[index].Id
148 | scriptcontext.doc.Views.Redraw()
149 | return rc
150 |
151 |
152 | def AddSpotLight(origin, radius, apex_point):
153 | """Adds a new spot light object to the document
154 | Parameters:
155 | origin (point): 3d origin point of the light
156 | radius (number): radius of the cone
157 | apex_point (point): 3d apex point of the light
158 | Returns:
159 | guid: identifier of the new object
160 | Example:
161 | import rhinoscriptsyntax as rs
162 | radius = 5.0
163 | origin = rs.GetPoint("Base of cone")
164 | if origin:
165 | apex = rs.GetPoint("End of cone", origin)
166 | if apex: rs.AddSpotLight(origin, radius, apex)
167 | See Also:
168 | IsSpotLight
169 | SpotLightHardness
170 | SpotLightShadowIntensity
171 | """
172 | origin = rhutil.coerce3dpoint(origin, True)
173 | apex_point = rhutil.coerce3dpoint(apex_point, True)
174 | if radius<0: radius=1.0
175 | light = Rhino.Geometry.Light()
176 | light.LightStyle = Rhino.Geometry.LightStyle.WorldSpot
177 | light.Location = apex_point
178 | light.Direction = origin-apex_point
179 | light.SpotAngleRadians = math.atan(radius / (light.Direction.Length))
180 | light.HotSpot = 0.50
181 | index = scriptcontext.doc.Lights.Add(light)
182 | if index<0: raise Exception("unable to add light to LightTable")
183 | rc = scriptcontext.doc.Lights[index].Id
184 | scriptcontext.doc.Views.Redraw()
185 | return rc
186 |
187 |
188 | def EnableLight(object_id, enable=None):
189 | """Enables or disables a light object
190 | Parameters:
191 | object_id (guid): the light object's identifier
192 | enable (bool, optional): the light's enabled status
193 | Returns:
194 | bool: if enable is not specified, the current enabled status
195 | bool: if enable is specified, the previous enabled status
196 | None: on error
197 | Example:
198 | import rhinoscriptsyntax as rs
199 | id = rs.GetObject("Select light", rs.filter.light)
200 | if id: rs.EnableLight( id, False )
201 | See Also:
202 | IsLight
203 | IsLightEnabled
204 | LightColor
205 | LightCount
206 | LightName
207 | LightObjects
208 | """
209 | light = __coercelight(object_id, True)
210 | rc = light.IsEnabled
211 | if enable is not None and enable!=rc:
212 | light.IsEnabled = enable
213 | id = rhutil.coerceguid(object_id)
214 | if not scriptcontext.doc.Lights.Modify(id, light):
215 | return scriptcontext.errorhandler()
216 | scriptcontext.doc.Views.Redraw()
217 | return rc
218 |
219 |
220 | def IsDirectionalLight(object_id):
221 | """Verifies a light object is a directional light
222 | Parameters:
223 | object_id (guid): the light object's identifier
224 | Returns:
225 | bool: True or False
226 | Example:
227 | import rhinoscriptsyntax as rs
228 | id = rs.GetObject("Select a light", rs.filter.light)
229 | if rs.IsDirectionalLight(id):
230 | print("The object is a directional light.")
231 | else:
232 | print("The object is not a directional light.")
233 | See Also:
234 | AddDirectionalLight
235 | """
236 | light = __coercelight(object_id, True)
237 | return light.IsDirectionalLight
238 |
239 |
240 | def IsLight(object_id):
241 | """Verifies an object is a light object
242 | Parameters:
243 | object_id (guid): the light object's identifier
244 | Returns:
245 | bool: True or False
246 | Example:
247 | import rhinoscriptsyntax as rs
248 | id = rs.GetObject("Select a light")
249 | if rs.IsLight(id):
250 | print("The object is a light.")
251 | else:
252 | print("The object is not a light.")
253 | See Also:
254 | EnableLight
255 | IsLightEnabled
256 | LightColor
257 | LightCount
258 | LightName
259 | LightObjects
260 | """
261 | light = __coercelight(object_id, False)
262 | return light is not None
263 |
264 |
265 | def IsLightEnabled(object_id):
266 | """Verifies a light object is enabled
267 | Parameters:
268 | object_id (guid): the light object's identifier
269 | Returns:
270 | bool: True or False
271 | Example:
272 | import rhinoscriptsyntax as rs
273 | id = rs.GetObject("Select a light", rs.filter.light)
274 | if rs.IsLightEnabled(id):
275 | print("The light is enabled (on).")
276 | else:
277 | print("The light is disabled (off).")
278 | See Also:
279 | EnableLight
280 | IsLight
281 | LightColor
282 | LightCount
283 | LightName
284 | LightObjects
285 | """
286 | light = __coercelight(object_id, True)
287 | return light.IsEnabled
288 |
289 |
290 | def IsLightReference(object_id):
291 | """Verifies a light object is referenced from another file
292 | Parameters:
293 | object_id (guid): the light object's identifier
294 | Returns:
295 | bool: True or False
296 | Example:
297 | import rhinoscriptsyntax as rs
298 | id = rs.GetObject("Select a light", rs.filter.light)
299 | if rs.IsLightReference(id):
300 | print("The light is a reference object.")
301 | else:
302 | print("The light is not a reference object.")
303 | See Also:
304 | IsObjectReference
305 | """
306 | light = __coercelight(object_id, True)
307 | return light.IsReference
308 |
309 |
310 | def IsLinearLight(object_id):
311 | """Verifies a light object is a linear light
312 | Parameters:
313 | object_id (guid): the light object's identifier
314 | Returns:
315 | bool: True or False
316 | Example:
317 | import rhinoscriptsyntax as rs
318 | id = rs.GetObject("Select a light", rs.filter.light)
319 | if rs.IsLinearLight(id):
320 | print("The object is a linear light.")
321 | else:
322 | print("The object is not a linear light.")
323 | See Also:
324 | AddLinearLight
325 | """
326 | light = __coercelight(object_id, True)
327 | return light.IsLinearLight
328 |
329 |
330 | def IsPointLight(object_id):
331 | """Verifies a light object is a point light
332 | Parameters:
333 | object_id (guid): the light object's identifier
334 | Returns:
335 | bool: True or False
336 | Example:
337 | import rhinoscriptsyntax as rs
338 | id = rs.GetObject("Select a light", rs.filter.light)
339 | if rs.IsPointLight(id):
340 | print("The object is a point light.")
341 | else:
342 | print("The object is not a point light.")
343 | See Also:
344 | AddPointLight
345 | """
346 | light = __coercelight(object_id, True)
347 | return light.IsPointLight
348 |
349 |
350 | def IsRectangularLight(object_id):
351 | """Verifies a light object is a rectangular light
352 | Parameters:
353 | object_id (guid): the light object's identifier
354 | Returns:
355 | bool: True or False
356 | Example:
357 | import rhinoscriptsyntax as rs
358 | id = rs.GetObject("Select a light", rs.filter.light)
359 | if rs.IsRectangularLight(id):
360 | print("The object is a rectangular light.")
361 | else:
362 | print("The object is not a rectangular light.")
363 | See Also:
364 | AddRectangularLight
365 | """
366 | light = __coercelight(object_id, True)
367 | return light.IsRectangularLight
368 |
369 |
370 | def IsSpotLight(object_id):
371 | """Verifies a light object is a spot light
372 | Parameters:
373 | object_id (guid): the light object's identifier
374 | Returns:
375 | bool: True or False
376 | Example:
377 | import rhinoscriptsyntax as rs
378 | id = rs.GetObject("Select a light", rs.filter.light)
379 | if rs.IsSpotLight(id):
380 | print("The object is a spot light.")
381 | else:
382 | print("The object is not a spot light.")
383 | See Also:
384 | AddSpotLight
385 | SpotLightHardness
386 | SpotLightShadowIntensity
387 | """
388 | light = __coercelight(object_id, True)
389 | return light.IsSpotLight
390 |
391 |
392 | def LightColor(object_id, color=None):
393 | """Returns or changes the color of a light
394 | Parameters:
395 | object_id (guid): the light object's identifier
396 | color (color, optional): the light's new color
397 | Returns:
398 | color: if color is not specified, the current color
399 | color: if color is specified, the previous color
400 | Example:
401 | import rhinoscriptsyntax as rs
402 | id = rs.GetObject("Select a light", rs.filter.light)
403 | if id: rs.LightColor( id, (0,255,255) )
404 | See Also:
405 | EnableLight
406 | IsLight
407 | IsLightEnabled
408 | LightCount
409 | LightName
410 | LightObjects
411 | """
412 | light = __coercelight(object_id, True)
413 | rc = light.Diffuse
414 | if color:
415 | color = rhutil.coercecolor(color, True)
416 | if color!=rc:
417 | light.Diffuse = color
418 | id = rhutil.coerceguid(object_id, True)
419 | if not scriptcontext.doc.Lights.Modify(id, light):
420 | return scriptcontext.errorhandler()
421 | scriptcontext.doc.Views.Redraw()
422 | return rc
423 |
424 |
425 | def LightCount():
426 | """Returns the number of light objects in the document
427 | Returns:
428 | number: the number of light objects in the document
429 | Example:
430 | import rhinoscriptsyntax as rs
431 | print("There are {} lights".format(rs.LightCount()))
432 | See Also:
433 | EnableLight
434 | IsLight
435 | IsLightEnabled
436 | LightColor
437 | LightName
438 | LightObjects
439 | """
440 | return scriptcontext.doc.Lights.Count
441 |
442 |
443 | def LightDirection(object_id, direction=None):
444 | """Returns or changes the direction of a light object
445 | Parameters:
446 | object_id (guid): the light object's identifier
447 | direction (vector, optional): the light's new direction
448 | Returns:
449 | vector: if direction is not specified, the current direction
450 | vector: if direction is specified, the previous direction
451 | Example:
452 | import rhinoscriptsyntax as rs
453 | id = rs.GetObject("Select a light", rs.filter.light)
454 | if id: print( rs.LightDirection(id) )
455 | See Also:
456 | IsLight
457 | LightLocation
458 | """
459 | light = __coercelight(object_id, True)
460 | rc = light.Direction
461 | if direction:
462 | direction = rhutil.coerce3dvector(direction, True)
463 | if direction!=rc:
464 | light.Direction = direction
465 | id = rhutil.coerceguid(object_id, True)
466 | if not scriptcontext.doc.Lights.Modify(id, light):
467 | return scriptcontext.errorhandler()
468 | scriptcontext.doc.Views.Redraw()
469 | return rc
470 |
471 |
472 | def LightLocation(object_id, location=None):
473 | """Returns or changes the location of a light object
474 | Parameters:
475 | object_id (guid): the light object's identifier
476 | location (point, optional): the light's new location
477 | Returns:
478 | point: if location is not specified, the current location
479 | point: if location is specified, the previous location
480 | Example:
481 | import rhinoscriptsyntax as rs
482 | id = rs.GetObject("Select a light", rs.filter.light)
483 | if id: rs.AddPoint( rs.LightLocation(id) )
484 | See Also:
485 | IsLight
486 | LightDirection
487 | """
488 | light = __coercelight(object_id, True)
489 | rc = light.Location
490 | if location:
491 | location = rhutil.coerce3dpoint(location, True)
492 | if location!=rc:
493 | light.Location = location
494 | id = rhutil.coerceguid(object_id, True)
495 | if not scriptcontext.doc.Lights.Modify(id, light):
496 | return scriptcontext.errorhandler()
497 | scriptcontext.doc.Views.Redraw()
498 | return rc
499 |
500 |
501 | def LightName(object_id, name=None):
502 | """Returns or changes the name of a light object
503 | Parameters:
504 | object_id (guid): the light object's identifier
505 | name (str, optional): the light's new name
506 | Returns:
507 | str: if name is not specified, the current name
508 | str: if name is specified, the previous name
509 | Example:
510 | import rhinoscriptsyntax as rs
511 | id = rs.GetObject("Select a light", rs.filter.light)
512 | if id:
513 | name = rs.GetString("New light name")
514 | if name: rs.LightName(id, name)
515 | See Also:
516 | EnableLight
517 | IsLight
518 | IsLightEnabled
519 | LightColor
520 | LightCount
521 | LightObjects
522 | """
523 | light = __coercelight(object_id, True)
524 | rc = light.Name
525 | if name and name!=rc:
526 | light.Name = name
527 | id = rhutil.coerceguid(object_id, True)
528 | if not scriptcontext.doc.Lights.Modify(id, light):
529 | return scriptcontext.errorhandler()
530 | scriptcontext.doc.Views.Redraw()
531 | return rc
532 |
533 |
534 | def LightObjects():
535 | """Returns list of identifiers of light objects in the document
536 | Returns:
537 | list(guid, ...): the list of identifiers of light objects in the document
538 | Example:
539 | import rhinoscriptsyntax as rs
540 | lights = rs.LightObjects()
541 | if lights:
542 | rs.AddLayer( "Lights" )
543 | for light in lights: rs.ObjectLayer( light, "Lights" )
544 | See Also:
545 | EnableLight
546 | IsLight
547 | IsLightEnabled
548 | LightColor
549 | LightCount
550 | LightName
551 | """
552 | count = scriptcontext.doc.Lights.Count
553 | rc = []
554 | for i in range(count):
555 | rhlight = scriptcontext.doc.Lights[i]
556 | if not rhlight.IsDeleted: rc.append(rhlight.Id)
557 | return rc
558 |
559 |
560 | def RectangularLightPlane(object_id):
561 | """Returns the plane of a rectangular light object
562 | Parameters:
563 | object_id (guid): the light object's identifier
564 | Returns:
565 | plane: the plane if successful
566 | None: on error
567 | Example:
568 | import rhinoscriptsyntax as rs
569 | id = rs.GetObject("Select a rectangular light", rs.filter.light)
570 | if id:
571 | rc = rs.RectangularLightPlane(id)
572 | if rc:
573 | plane, extents = rc
574 | rs.AddPlaneSurface( plane, extents[0], extents[1] )
575 | See Also:
576 | IsRectangularLight
577 | """
578 | light = __coercelight(object_id, True)
579 | if light.LightStyle!=Rhino.Geometry.LightStyle.WorldRectangular:
580 | return scriptcontext.errorhandler()
581 | location = light.Location
582 | length = light.Length
583 | width = light.Width
584 | direction = light.Direction
585 | plane = Rhino.Geometry.Plane(location, length, width)
586 | return plane, (length.Length, width.Length)
587 |
588 |
589 | def SpotLightHardness(object_id, hardness=None):
590 | """Returns or changes the hardness of a spot light. Spotlight hardness
591 | controls the fully illuminated region.
592 | Parameters:
593 | object_id (guid): the light object's identifier
594 | hardness (number, optional): the light's new hardness
595 | Returns:
596 | number: if hardness is not specified, the current hardness
597 | number: if hardness is specified, the previous hardness
598 | Example:
599 | import rhinoscriptsyntax as rs
600 | id = rs.GetObject("Select a light", rs.filter.light)
601 | if id: rs.SpotLightHardness(id, 0.75)
602 | See Also:
603 | AddSpotLight
604 | IsSpotLight
605 | SpotLightRadius
606 | SpotLightShadowIntensity
607 | """
608 | light = __coercelight(object_id, True)
609 | if light.LightStyle!=Rhino.Geometry.LightStyle.WorldSpot:
610 | return scriptcontext.errorhandler()
611 | rc = light.HotSpot
612 | if hardness and hardness!=rc:
613 | light.HotSpot = hardness
614 | id = rhutil.coerceguid(object_id, True)
615 | if not scriptcontext.doc.Lights.Modify(id, light):
616 | return scriptcontext.errorhandler()
617 | scriptcontext.doc.Views.Redraw()
618 | return rc
619 |
620 |
621 | def SpotLightRadius(object_id, radius=None):
622 | """Returns or changes the radius of a spot light.
623 | Parameters:
624 | object_id (guid): the light object's identifier
625 | radius (number, optional): the light's new radius
626 | Returns:
627 | number: if radius is not specified, the current radius
628 | number: if radius is specified, the previous radius
629 | Example:
630 | import rhinoscriptsyntax as rs
631 | id = rs.GetObject("Select a light", rs.filter.light)
632 | if id: rs.SpotLightRadius(id, 5.0)
633 | See Also:
634 | AddSpotLight
635 | IsSpotLight
636 | SpotLightHardness
637 | SpotLightShadowIntensity
638 | """
639 | light = __coercelight(object_id, True)
640 | if light.LightStyle!=Rhino.Geometry.LightStyle.WorldSpot:
641 | return scriptcontext.errorhandler()
642 | radians = light.SpotAngleRadians
643 | rc = light.Direction.Length * math.tan(radians)
644 | if radius and radius!=rc:
645 | radians = math.atan(radius/light.Direction.Length)
646 | light.SpotAngleRadians = radians
647 | id = rhutil.coerceguid(object_id, True)
648 | if not scriptcontext.doc.Lights.Modify(id, light):
649 | return scriptcontext.errorhandler()
650 | scriptcontext.doc.Views.Redraw()
651 | return rc
652 |
653 |
654 | def SpotLightShadowIntensity(object_id, intensity=None):
655 | """Returns or changes the shadow intensity of a spot light.
656 | Parameters:
657 | object_id (guid): the light object's identifier
658 | intensity (number, optional): the light's new intensity
659 | Returns:
660 | number: if intensity is not specified, the current intensity
661 | number: if intensity is specified, the previous intensity
662 | Example:
663 | import rhinoscriptsyntax as rs
664 | id = rs.GetObject("Select a light", rs.filter.light)
665 | if id: rs.SpotLightShadowIntensity(id, 0.75)
666 | See Also:
667 | AddSpotLight
668 | IsSpotLight
669 | SpotLightHardness
670 | SpotLightRadius
671 | """
672 | light = __coercelight(object_id, True)
673 | if light.LightStyle!=Rhino.Geometry.LightStyle.WorldSpot:
674 | return scriptcontext.errorhandler()
675 | rc = light.SpotLightShadowIntensity
676 | if intensity and intensity!=rc:
677 | light.SpotLightShadowIntensity = intensity
678 | id = rhutil.coerceguid(object_id, True)
679 | if not scriptcontext.doc.Lights.Modify(id, light):
680 | return scriptcontext.errorhandler()
681 | scriptcontext.doc.Views.Redraw()
682 | return rc
683 |
```
--------------------------------------------------------------------------------
/rhino_mcp_server/static/block.py:
--------------------------------------------------------------------------------
```python
1 | import math
2 |
3 | import System
4 |
5 | import Rhino
6 |
7 | import scriptcontext
8 |
9 | from rhinoscript import utility as rhutil
10 |
11 |
12 | def __InstanceObjectFromId(id, raise_if_missing):
13 | rhobj = rhutil.coercerhinoobject(id, True, raise_if_missing)
14 | if isinstance(rhobj, Rhino.DocObjects.InstanceObject): return rhobj
15 | if raise_if_missing: raise ValueError("unable to find InstanceObject")
16 |
17 |
18 | def AddBlock(object_ids, base_point, name=None, delete_input=False):
19 | """Adds a new block definition to the document
20 | Parameters:
21 | object_ids ([guid, ....]) objects that will be included in the block
22 | base_point (point): 3D base point for the block definition
23 | name (str, optional): name of the block definition. If omitted a name will be
24 | automatically generated
25 | delete_input (bool): if True, the object_ids will be deleted
26 | Returns:
27 | str: name of new block definition on success
28 | Example:
29 | import rhinoscriptsyntax as rs
30 | objs = rs.GetObjects("Select objects to define block")
31 | if objs:
32 | point = rs.GetPoint("Block base point")
33 | if point:
34 | block = rs.AddBlock(objs, point, None, True)
35 | rs.InsertBlock(block, point)
36 | See Also:
37 | InsertBlock
38 | """
39 | base_point = rhutil.coerce3dpoint(base_point, True)
40 | if not name:
41 | name = scriptcontext.doc.InstanceDefinitions.GetUnusedInstanceDefinitionName()
42 | found = scriptcontext.doc.InstanceDefinitions.Find(name)
43 | objects = []
44 | for id in object_ids:
45 | obj = rhutil.coercerhinoobject(id, True)
46 | if obj.IsReference: return
47 | ot = obj.ObjectType
48 | if ot==Rhino.DocObjects.ObjectType.Light: return
49 | if ot==Rhino.DocObjects.ObjectType.Grip: return
50 | if ot==Rhino.DocObjects.ObjectType.Phantom: return
51 | if ot==Rhino.DocObjects.ObjectType.InstanceReference and found:
52 | uses, nesting = obj.UsesDefinition(found.Index)
53 | if uses: return
54 | objects.append(obj)
55 | if objects:
56 | geometry = [obj.Geometry for obj in objects]
57 | attrs = [obj.Attributes for obj in objects]
58 | rc = 0
59 | if found:
60 | rc = scriptcontext.doc.InstanceDefinitions.ModifyGeometry(found.Index, geometry, attrs)
61 | else:
62 | rc = scriptcontext.doc.InstanceDefinitions.Add(name, "", base_point, geometry, attrs)
63 | if rc>=0:
64 | if delete_input:
65 | for obj in objects: scriptcontext.doc.Objects.Delete(obj, True)
66 | scriptcontext.doc.Views.Redraw()
67 | return name
68 |
69 |
70 | def BlockContainerCount(block_name):
71 | """Returns number of block definitions that contain a specified
72 | block definition
73 | Parameters:
74 | block_name (str): the name of an existing block definition
75 | Returns:
76 | number: the number of block definitions that contain a specified block definition
77 | Example:
78 | import rhinoscriptscriptsyntax as rs
79 | block = rs.GetString("Block name to query")
80 | if rs.IsBlock(block):
81 | count = rs.BlockContainerCount(block)
82 | print("This block is nested in {} block(s).".format(count))
83 | See Also:
84 | BlockContainers
85 | IsBlock
86 | """
87 | return len(BlockContainers(block_name))
88 |
89 |
90 | def BlockContainers(block_name):
91 | """Returns names of the block definitions that contain a specified block
92 | definition.
93 | Parameters:
94 | block_name (str): the name of an existing block definition
95 | Returns:
96 | list(str, ...): A list of block definition names
97 | Example:
98 | import rhinoscriptsyntax as rs
99 | blockname = rs.GetString("Block name to query")
100 | if rs.IsBlock(blockname):
101 | blocks = rs.BlockContainers(blockname)
102 | for block in blocks: print(block)
103 | See Also:
104 | BlockContainerCount
105 | IsBlock
106 | """
107 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
108 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
109 | containers = idef.GetContainers()
110 | rc = []
111 | for item in containers:
112 | if not item.IsDeleted: rc.append(item.Name)
113 | return rc
114 |
115 |
116 | def BlockCount():
117 | """Returns the number of block definitions in the document
118 | Returns:
119 | number: the number of block definitions in the document
120 | Example:
121 | import rhinoscriptsyntax as rs
122 | count = rs.BlockCount()
123 | print("There are {} blocks".format(count)
124 | See Also:
125 | BlockNames
126 | IsBlock
127 | """
128 | return scriptcontext.doc.InstanceDefinitions.ActiveCount
129 |
130 |
131 | def BlockDescription(block_name, description=None):
132 | """Returns or sets the description of a block definition
133 | Parameters:
134 | block_name (str): the name of an existing block definition
135 | description (str, optional): The new description.
136 | Returns:
137 | str: if description is not specified, the current description
138 | str: if description is specified, the previous description
139 | Example:
140 | import rhinoscriptsyntax as rs
141 | blockname = rs.GetString("Block name to list description")
142 | if rs.IsBlock(blockname):
143 | desc = rs.BlockDescription(blockname)
144 | if desc is None: print("No description")
145 | else: print(desc)
146 | See Also:
147 | IsBlock
148 | """
149 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
150 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
151 | rc = idef.Description
152 | if description: scriptcontext.doc.InstanceDefinitions.Modify( idef, idef.Name, description, True )
153 | return rc
154 |
155 |
156 | def BlockInstanceCount(block_name,where_to_look=0):
157 | """Counts number of instances of the block in the document.
158 | Nested instances are not included in the count.
159 | Parameters:
160 | block_name (str): the name of an existing block definition
161 | where_to_look (number, optional):
162 | 0 = get top level references in active document.
163 | 1 = get top level and nested references in active document.
164 | 2 = check for references from other instance definitions
165 | Returns:
166 | number: the number of instances of the block in the document
167 | Example:
168 | import rhinoscriptsyntax as rs
169 | blockname = rs.GetString("Block to count")
170 | if rs.IsBlock(blockname):
171 | count = rs.BlockInstanceCount(blockname)
172 | print("{} block(s) found.".format(count))
173 | See Also:
174 | BlockInstanceInsertPoint
175 | BlockInstances
176 | BlockInstanceXform
177 | IsBlockInstance
178 | """
179 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
180 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
181 | refs = idef.GetReferences(where_to_look)
182 | return len(refs)
183 |
184 |
185 | def BlockInstanceInsertPoint(object_id):
186 | """Returns the insertion point of a block instance.
187 | Parameters:
188 | object_id (guid): The identifier of an existing block insertion object
189 | Returns:
190 | point: The insertion 3D point if successful
191 | Example:
192 | import rhinoscriptsyntax as rs
193 | strObject = rs.GetObject("Select block")
194 | if rs.IsBlockInstance(strObject):
195 | rs.AddPoint( rs.BlockInstanceInsertPoint(strObject) )
196 | See Also:
197 | BlockInstanceCount
198 | BlockInstances
199 | BlockInstanceXform
200 | IsBlockInstance
201 | """
202 | instance = __InstanceObjectFromId(object_id, True)
203 | xf = instance.InstanceXform
204 | pt = Rhino.Geometry.Point3d.Origin
205 | pt.Transform(xf)
206 | return pt
207 |
208 |
209 | def BlockInstanceName(object_id):
210 | """Returns the block name of a block instance
211 | Parameters:
212 | object_id (guid): The identifier of an existing block insertion object
213 | Returns:
214 | str: the block name of a block instance
215 | Example:
216 | import rhinoscriptsyntax as rs
217 | strObject = rs.GetObject("Select block")
218 | if rs.IsBlockInstance(strObject):
219 | print(rs.BlockInstanceName(strObject))
220 | See Also:
221 | BlockInstanceCount
222 | BlockInstances
223 | BlockInstanceXform
224 | IsBlockInstance
225 | """
226 | instance = __InstanceObjectFromId(object_id, True)
227 | idef = instance.InstanceDefinition
228 | return idef.Name
229 |
230 |
231 | def BlockInstances(block_name,where_to_look=0):
232 | """Returns the identifiers of the inserted instances of a block.
233 | Parameters:
234 | block_name (str): the name of an existing block definition
235 | where_to_look (number, optional):
236 | 0 = get top level references in active document.
237 | 1 = get top level and nested references in active document.
238 | 2 = check for references from other instance definitions
239 | Returns:
240 | list(guid, ...): Ids identifying the instances of a block in the model.
241 | Example:
242 | import rhinoscriptsyntax as rs
243 | strBlock = rs.GetString("Block to select")
244 | if rs.IsBlock(strBlock):
245 | arrObjects = rs.BlockInstances(strBlock)
246 | if arrobjects:
247 | rs.SelectObjects(arrObjects)
248 | See Also:
249 | BlockInstanceCount
250 | BlockInstanceInsertPoint
251 | BlockInstanceXform
252 | IsBlockInstance
253 | """
254 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
255 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
256 | instances = idef.GetReferences(where_to_look)
257 | return [item.Id for item in instances]
258 |
259 |
260 | def BlockInstanceXform(object_id):
261 | """Returns the location of a block instance relative to the world coordinate
262 | system origin (0,0,0). The position is returned as a 4x4 transformation
263 | matrix
264 | Parameters:
265 | object_id (guid): The identifier of an existing block insertion object
266 | Returns:
267 | transform: the location, as a transform matrix, of a block instance relative to the world coordinate
268 | system origin
269 | Example:
270 | import rhinoscriptsyntax as rs
271 | obj = rs.GetObject("Select block to query")
272 | if rs.IsBlockInstance(obj):
273 | arrMatrix = rs.BlockInstanceXform(obj)
274 | if arrMatrix is not None:
275 | pointId = rs.AddPoint([0,0,0])
276 | rs.TransformObject( pointId, arrMatrix)
277 | See Also:
278 | BlockInstanceCount
279 | BlockInstanceInsertPoint
280 | BlockInstances
281 | IsBlockInstance
282 | """
283 | instance = __InstanceObjectFromId(object_id, True)
284 | return instance.InstanceXform
285 |
286 |
287 | def BlockNames( sort=False ):
288 | """Returns the names of all block definitions in the document
289 | Parameters:
290 | sort (bool): True to return a sorted list
291 | Returns:
292 | list(str, ...): the names of all block definitions in the document
293 | Example:
294 | import rhinoscriptsyntax as rs
295 | names = rs.BlockNames(True)
296 | if names:
297 | for name in names: print(name)
298 | See Also:
299 | BlockCount
300 | IsBlock
301 | """
302 | ideflist = scriptcontext.doc.InstanceDefinitions.GetList(True)
303 | rc = [item.Name for item in ideflist]
304 | if(sort): rc.sort()
305 | return rc
306 |
307 |
308 | def BlockObjectCount(block_name):
309 | """Returns number of objects that make up a block definition
310 | Parameters:
311 | block_name (str): name of an existing block definition
312 | Returns:
313 | number: the number of objects that make up a block definition
314 | Example:
315 | import rhinoscriptsyntax as rs
316 | count = rs.BlockObjectCount()
317 | print("There are {} blocks".format(count))
318 | See Also:
319 | BlockNames
320 | BlockObjects
321 | IsBlock
322 | """
323 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
324 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
325 | return idef.ObjectCount
326 |
327 |
328 | def BlockObjects(block_name):
329 | """Returns identifiers of the objects that make up a block definition
330 | Parameters:
331 | block_name (str): name of an existing block definition
332 | Returns:
333 | list(guid, ...): list of identifiers on success
334 | Example:
335 | import rhinoscriptsyntax as rs
336 | strBlock = rs.GetString("Block name to list identifiers")
337 | if rs.IsBlock(strBlock):
338 | objects = rs.BlockObjects(strBlock)
339 | if objects:
340 | for item in objects: print(item)
341 | See Also:
342 | BlockNames
343 | BlockObjectCount
344 | IsBlock
345 | """
346 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
347 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
348 | rhobjs = idef.GetObjects()
349 | return [obj.Id for obj in rhobjs]
350 |
351 |
352 | def BlockPath(block_name):
353 | """Returns path to the source of a linked or embedded block definition.
354 | A linked or embedded block definition is a block definition that was
355 | inserted from an external file.
356 | Parameters:
357 | block_name (str): name of an existing block definition
358 | Returns:
359 | str: path to the linked block on success
360 | Example:
361 | import rhinoscriptsyntax as rs
362 | strBlock = rs.GetString("Block name to list path")
363 | if rs.IsBlockEmbedded(strBlock):
364 | print(rs.BlockPath(strBlock))
365 | See Also:
366 | IsBlock
367 | IsBlockEmbedded
368 | """
369 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
370 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
371 | return idef.SourceArchive
372 |
373 |
374 | def BlockStatus(block_name):
375 | """Returns the status of a linked block
376 | Parameters:
377 | block_name (str): Name of an existing block
378 | Returns:
379 | number: the status of a linked block
380 | Value Description
381 | -3 Not a linked block definition.
382 | -2 The linked block definition's file could not be opened or could not be read.
383 | -1 The linked block definition's file could not be found.
384 | 0 The linked block definition is up-to-date.
385 | 1 The linked block definition's file is newer than definition.
386 | 2 The linked block definition's file is older than definition.
387 | 3 The linked block definition's file is different than definition.
388 | Example:
389 | import rhinoscriptsyntax as rs
390 | block = rs.GetString("Block name to list description")
391 | if rs.IsBlock(block):
392 | status = rs.BlockStatus(block)
393 | print("block status for {} is {}".format(block, status))
394 | See Also:
395 | IsBlock
396 | """
397 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
398 | if not idef: return -3
399 | return int(idef.ArchiveFileStatus)
400 |
401 |
402 | def DeleteBlock(block_name):
403 | """Deletes a block definition and all of it's inserted instances.
404 | Parameters:
405 | block_name (str): name of an existing block definition
406 | Returns:
407 | bool: True or False indicating success or failure
408 | Example:
409 | import rhinoscriptsyntax as rs
410 | strBlock = rs.GetString("Block name to delete")
411 | if rs.IsBlock(strBlock):
412 | rs.DeleteBlock(strBlock)
413 | See Also:
414 | BlockNames
415 | ExplodeBlockInstance
416 | IsBlock
417 | """
418 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
419 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
420 | rc = scriptcontext.doc.InstanceDefinitions.Delete(idef.Index, True, False)
421 | scriptcontext.doc.Views.Redraw()
422 | return rc
423 |
424 |
425 | def ExplodeBlockInstance(object_id, explode_nested_instances=False):
426 | """Explodes a block instance into it's geometric components. The
427 | exploded objects are added to the document
428 | Parameters:
429 | object_id (guid): The identifier of an existing block insertion object
430 | explode_nested_instances (bool, optional): By default nested blocks are not exploded.
431 | Returns:
432 | list(guid, ...): identifiers for the newly exploded objects on success
433 | Example:
434 | import rhinoscriptsyntax as rs
435 | strObject = rs.GetObject("Select block instance to explode")
436 | if rs.IsBlockInstance(strObject):
437 | rs.ExplodeBlockInstance(strObject)
438 | See Also:
439 | DeleteBlock
440 | IsBlockInstance
441 | """
442 | instance = __InstanceObjectFromId(object_id, True)
443 | guids = scriptcontext.doc.Objects.AddExplodedInstancePieces(instance, explodeNestedInstances=explode_nested_instances, deleteInstance=True)
444 | if guids:
445 | scriptcontext.doc.Views.Redraw()
446 | return guids
447 |
448 |
449 | def InsertBlock( block_name, insertion_point, scale=(1,1,1), angle_degrees=0, rotation_normal=(0,0,1) ):
450 | """Inserts a block whose definition already exists in the document
451 | Parameters:
452 | block_name (str): name of an existing block definition
453 | insertion_point (point): insertion point for the block
454 | scale ({number, number, number]): x,y,z scale factors
455 | angle_degrees (number, optional): rotation angle in degrees
456 | rotation_normal (vector, optional): the axis of rotation.
457 | Returns:
458 | guid: id for the block that was added to the doc
459 | Example:
460 | See Also:
461 | """
462 | insertion_point = rhutil.coerce3dpoint(insertion_point, True)
463 | rotation_normal = rhutil.coerce3dvector(rotation_normal, True)
464 | angle_radians = math.radians(angle_degrees)
465 | trans = Rhino.Geometry.Transform
466 | move = trans.Translation(insertion_point[0],insertion_point[1],insertion_point[2])
467 | scale = trans.Scale(Rhino.Geometry.Plane.WorldXY, scale[0], scale[1], scale[2])
468 | rotate = trans.Rotation(angle_radians, rotation_normal, Rhino.Geometry.Point3d.Origin)
469 | xform = move * scale * rotate
470 | return InsertBlock2( block_name, xform )
471 |
472 |
473 | def InsertBlock2(block_name, xform):
474 | """Inserts a block whose definition already exists in the document
475 | Parameters:
476 | block_name (str): name of an existing block definition
477 | xform (transform): 4x4 transformation matrix to apply
478 | Returns:
479 | guid: id for the block that was added to the doc on success
480 | Example:
481 | See Also:
482 | """
483 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
484 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
485 | xform = rhutil.coercexform(xform, True)
486 | id = scriptcontext.doc.Objects.AddInstanceObject(idef.Index, xform )
487 | if id!=System.Guid.Empty:
488 | scriptcontext.doc.Views.Redraw()
489 | return id
490 |
491 |
492 | def IsBlock(block_name):
493 | """Verifies the existence of a block definition in the document.
494 | Parameters:
495 | block_name (str): name of an existing block definition
496 | Returns:
497 | bool: True or False
498 | Example:
499 | import rhinoscriptsyntax as rs
500 | strBlock = rs.GetString("Block name")
501 | if rs.IsBlock(strBlock):
502 | print("The block definition exists.")
503 | else:
504 | print("The block definition does not exist.")
505 | See Also:
506 | IsBlockEmbedded
507 | IsBlockInstance
508 | IsBlockInUse
509 | IsBlockReference
510 | """
511 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
512 | return (idef is not None)
513 |
514 |
515 | def IsBlockEmbedded(block_name):
516 | """Verifies a block definition is embedded, or linked, from an external file.
517 | Parameters:
518 | block_name (str): name of an existing block definition
519 | Returns:
520 | bool: True or False
521 | Example:
522 | import rhinoscriptsyntax as rs
523 | strBlock = rs.GetString("Block name")
524 | if rs.IsBlock(strBlock):
525 | if rs.IsBlockEmbedded(strBlock):
526 | print("The block definition is embedded.")
527 | else:
528 | print("The block definition is not embedded.")
529 | else:
530 | print("The block definition does not exist.")
531 | See Also:
532 | IsBlock
533 | IsBlockInstance
534 | IsBlockInUse
535 | IsBlockReference
536 | """
537 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
538 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
539 | ut = Rhino.DocObjects.InstanceDefinitionUpdateType
540 | return (idef.UpdateType==ut.Embedded or idef.UpdateType==ut.Static or idef.UpdateType==ut.LinkedAndEmbedded)
541 |
542 |
543 | def IsBlockInstance(object_id):
544 | """Verifies an object is a block instance
545 | Parameters:
546 | object_id (guid): The identifier of an existing block insertion object
547 | Returns:
548 | bool: True or False
549 | Example:
550 | import rhinoscriptsyntax as rs
551 | obj = rs.GetObject("Select block instance")
552 | if rs.IsBlockInstance(obj):
553 | print("The object is a block instance.")
554 | else:
555 | print("The object is not a block instance.")
556 | See Also:
557 | IsBlock
558 | IsBlockEmbedded
559 | IsBlockInUse
560 | IsBlockReference
561 | """
562 | return __InstanceObjectFromId(object_id, False) is not None
563 |
564 |
565 | def IsBlockInUse(block_name, where_to_look=0):
566 | """Verifies that a block definition is being used by an inserted instance
567 | Parameters:
568 | block_name (str): name of an existing block definition
569 | where_to_look (number, optional): One of the following values
570 | 0 = Check for top level references in active document
571 | 1 = Check for top level and nested references in active document
572 | 2 = Check for references in other instance definitions
573 | Returns:
574 | bool: True or False
575 | Example:
576 | import rhinoscriptsyntax as rs
577 | strBlock = rs.GetString("Block name")
578 | if rs.IsBlock(strBlock):
579 | if rs.IsBlockInUse(strBlock):
580 | print("The block definition is in use.")
581 | else:
582 | print("The block definition is not in use.")
583 | else:
584 | print("The block definition does not exist.")
585 | See Also:
586 | IsBlock
587 | IsBlockInstance
588 | IsBlockEmbedded
589 | IsBlockReference
590 | """
591 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
592 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
593 | return idef.InUse(where_to_look)
594 |
595 |
596 | def IsBlockReference(block_name):
597 | """Verifies that a block definition is from a reference file.
598 | Parameters:
599 | block_name (str): name of an existing block definition
600 | Returns:
601 | bool: True or False
602 | Example:
603 | import rhinoscriptsyntax as rs
604 | strBlock = rs.GetString("Block name")
605 | if rs.IsBlock(strBlock):
606 | if rs.IsBlockReference(strBlock):
607 | print("The block definition is a reference definition.")
608 | else:
609 | print("The block definition is not a reference definition.")
610 | else:
611 | print("The block definition does not exist.")
612 | See Also:
613 | IsBlock
614 | IsBlockEmbedded
615 | IsBlockInUse
616 | IsBlockInstance
617 | """
618 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
619 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
620 | return idef.IsReference
621 |
622 |
623 | def RenameBlock( block_name, new_name ):
624 | """Renames an existing block definition
625 | Parameters:
626 | block_name (str): name of an existing block definition
627 | new_name (str): name to change to
628 | Returns:
629 | bool: True or False indicating success or failure
630 | Example:
631 | import rhinoscriptsyntax as rs
632 | strOldBlock = rs.GetString("Old block name")
633 | if strOldBlock:
634 | strNewBlock = rs.GetString("New block name")
635 | if strNewBlock:
636 | rs.RenameBlock (strOldBlock, strNewBlock)
637 | See Also:
638 | BlockNames
639 | IsBlock
640 | """
641 | idef = scriptcontext.doc.InstanceDefinitions.Find(block_name)
642 | if not idef: raise ValueError("%s does not exist in InstanceDefinitionsTable"%block_name)
643 | description = idef.Description
644 | rc = scriptcontext.doc.InstanceDefinitions.Modify(idef, new_name, description, False)
645 | return rc
646 |
```