I use “RhinoDoc.Objects.Add”,and it return id,then I use “RhinoDoc.Objects.FindId” api can’t find this object.Is there a bug or something?
Seems to be working just fine here:
import scriptcontext as sc import Rhino.Geometry box = Rhino.Geometry.Box(Rhino.Geometry.Plane.WorldXY, Rhino.Geometry.Interval(0, 3), Rhino.Geometry.Interval(0, 3), Rhino.Geometry.Interval(0, 3) ).ToBrep() print(box) boxId = sc.doc.Objects.Add(box) print(boxId) foundObject = sc.doc.Objects.FindId(boxId) print(foundObject)
Can you please save your 3dm with the object you created by code and attach it here?
Output from above script looks like:
<Rhino.Geometry.Brep object at 0x000000000000002B [Rhino.Geometry.Brep]> 87aee53d-804b-42e5-8b3b-8cadb486839c BrepObject: (unnamed) (0)
duzhengjie is my colleague. The problem we are encountering now is that in some special cases, after calling the RhinoDoc.Objects.Add() method, an ID will be returned, but we use this ID to call RhinoDoc.Objects.FindId( Id) but get a null result, and the result of RhinoDoc.Objects.Tolist() doesn’t have the data just added. We want to know, in what scenario, this error will be caused. Also, our actions that caused this error all happened after executing the Copy command. After we execute the Copy command, we will re-operate the RhinoObject once, and then trigger this error. This error appeared suddenly, and there was no problem before.
duzhengjie 是我的同事，我们现在遇到的问题是，在某些特殊情况下，调用 RhinoDoc.Objects.Add()方法后，会返回一个ID，但是我们用这个ID去调用 RhinoDoc.Objects.FindId(Id)却得到一个null的结果，并且 RhinoDoc.Objects.Tolist()的结果也没有刚刚添加的数据。我们想知道，在什么场景下，会导致这个错误。另外，我们导致这个错误的操作全都发生在执行 Copy 命令后。我们执行 Copy 命令后，会自己去重新操作一次 RhinoObject，然后触发了这个错误，这个错误是突然出现的，之前没有问题。
I’ll test this with Copy command too when I am back at my machine. In the meantime, please attach to a reply a simple 3dm file in which this happens for you
Please attach a 3dm file and a short self-contained script that reproduces the problem for you.
a returned Id could be pointing to nothing when the object cannot be added to the document. This is the case eg. when the object is a bad object. You can test the Id ike so:
new_id = scriptcontext.doc.Objects.AddBrep(brep) if new_id == System.Guid.Empty: print "Error - Id is empty"
also note the method you use for adding the object:
RhinoDoc.Objects.Add is extra picky sometimes with some object types as it needs to figure out what type the object is before adding. I’ve found there are types which it doesn’t like in the past. Please check if you could use a method which defines the type, eg.:
In case you expect an object to be problematic, check it before with eg.
brep.IsValidWithLog() to find out what makes it bad.
@clement very thanks for answering,here is an image for I testing,
please check if your variable
rId == System.Guid.Empty. If it is, try to check
segment.Geometry.IsValid before. What type of geometry is it ?
rid has displayed as image,it is “2fae03c5-3cbc-4de0-a752-f06538274c86”.This program runs well at first,but after coping a object,I reload it ,then it runs as this.
sorry, i am not sure i understand. Which object type is your
Types contain brep、curve,not only one,it means all types will be this.
Have you tried to detect type, eg. when it is brep use AddBrep or when curve use AddCurve ?
btw. is history enabled when you copy ?
Sorry, that’s our question, but another question that arises is, is there a way I can prevent the replication mechanism that comes with Rhino? That is, Rhino just informs me that the user is copying things, but I can tell Rhino not to actually copy it.
对不起，这是我们的问题，不过由此引发的另一个问题是，是否有办法可以让我阻止 Rhino 自带的复制机制？也就是说，Rhino只要通知我用户复制东西了，但我可以让 Rhino 不要自己真的去复制。
I’m not sure why copy would be involved here regardless of history being on or not. I maintain we do not know enough to understand what is happening. Again, attach a 3dm and fully contained code example to reproduce this where you get a valid Guid, but object is not found.
We are doing a copy function, we give a group of geometric figures a special meaning, for example, we call a certain group of figures a “wall”, now, we want to copy this wall, that is, to copy this group of figures , we will draw a new wall according to the parameters when drawing this wall at that time, in this way, we will generate a new RhinoObject, but because we can’t prevent Rhino’s built-in copy function, this leads to appearing in the same position Two identical graphics, in order to solve this problem, we try to delete the graphics generated by Rhino. However, due to the loopholes in the deletion mechanism we wrote, we have a problem in this topic. For the graph we just added, FindId returns null, because we deleted it by mistake, so it will be null. So, we want to be able to prevent Rhino from not copying this graphic, or to let Rhino just notify us that the user wants to copy it.
You can subscribe to Command.BeginCommand Event where you then check for CommandEventArgs.CommandEnglishName Property in your handler. Then check Command.EndCommand Event to know when the command has ended.
I still don’t get how your users would be able to delete objects between your
Objects.FindId() calls or how
_Copy affects between these two calls, as there is no way for correct plug-in code to run into such a situation. Unless you are doing actions on the
Objects table on a thread other than the main thread (which you never should do).
The obvious delete and add operations are invisible to the user, and we do it to delete the duplicate geometry generated by Rhino, and we didn’t expect to need an additional delete at first. Thanks for the suggestion, we will try it.
If you are doing deletes in the course of your code you may have to sit down and properly verify your code is doing what you think it is. Or verify that you properly understand what your code is doing
I hope you manage to find what causes this!
The probability of writing automated tests to crash Rhino is a bit high
Well yes, if you do the incorrect thing. If you are sure your code is correct and Rhino still crashes please submit steps to reproduce.