jupyter-cadquery: MyBinder Broken

I’m on Firefox 81 on Ubuntu 18.04 64-bit.

Is the binder still up to date and maintained? I was trying to help a CadQuery user on Discord get started with jupyter-cadquery, but we can’t get the binder to work. The user wants the widgets to dynamically adjust parameters.

https://mybinder.org/v2/gh/bernhard-42/jupyter-cadquery/v1.0.0?urlpath=lab&filepath=examples%2Fcadquery.ipynb

If I navigate to the examples directory and open cadquery-examples.ipynb, then execute the first two code cells, everything seems fine. But then if I try to execute cells further down, the 3D view doesn’t update. Trying different combinations of things causes other problems. If I call disable_replay() in the first cell then I start getting errors like this:

---------------------------------------------------------------------------
TraitError                                Traceback (most recent call last)
<ipython-input-9-2df1979a6696> in <module>
     10 result = cq.Workplane("XY").box(length, height, thickness)
     11 
---> 12 replay(result)

/srv/conda/envs/notebook/lib/python3.7/site-packages/jupyter_cadquery/cadquery/replay.py in replay(cad_obj, index, debug, cad_width, height)
    391         description='',
    392         disabled=False,
--> 393         layout=Layout(width="600px"))
    394     r.select_box.add_class("monospace")
    395     r.select_box.observe(r.select_handler)

/srv/conda/envs/notebook/lib/python3.7/site-packages/ipywidgets/widgets/widget_selection.py in __init__(self, *args, **kwargs)
    324         self._options_values = tuple(i[1] for i in options)
    325 
--> 326         super(_MultipleSelection, self).__init__(*args, **kwargs)
    327         self._initializing_traits_ = False
    328 

/srv/conda/envs/notebook/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in __init__(self, **kwargs)
    410         """Public constructor"""
    411         self._model_id = kwargs.pop('model_id', None)
--> 412         super(Widget, self).__init__(**kwargs)
    413 
    414         Widget._call_widget_constructed(self)

/srv/conda/envs/notebook/lib/python3.7/site-packages/traitlets/traitlets.py in __init__(self, *args, **kwargs)
    998                 else:
    999                     # passthrough args that don't set traits to super
-> 1000                     super_kwargs[key] = value
   1001         try:
   1002             super(HasTraits, self).__init__(*super_args, **super_kwargs)

/srv/conda/envs/notebook/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
    117         if type is None:
    118             try:
--> 119                 next(self.gen)
    120             except StopIteration:
    121                 return False

/srv/conda/envs/notebook/lib/python3.7/site-packages/traitlets/traitlets.py in hold_trait_notifications(self)
   1120                                 self._trait_values.pop(name)
   1121                 cache = {}
-> 1122                 raise e
   1123             finally:
   1124                 self._cross_validation_lock = False

/srv/conda/envs/notebook/lib/python3.7/site-packages/traitlets/traitlets.py in hold_trait_notifications(self)
   1106                 for name in list(cache.keys()):
   1107                     trait = getattr(self.__class__, name)
-> 1108                     value = trait._cross_validate(self, getattr(self, name))
   1109                     self.set_trait(name, value)
   1110             except TraitError as e:

/srv/conda/envs/notebook/lib/python3.7/site-packages/traitlets/traitlets.py in _cross_validate(self, obj, value)
    597         if self.name in obj._trait_validators:
    598             proposal = Bunch({'trait': self, 'value': value, 'owner': obj})
--> 599             value = obj._trait_validators[self.name](obj, proposal)
    600         elif hasattr(obj, '_%s_validate' % self.name):
    601             meth_name = '_%s_validate' % self.name

/srv/conda/envs/notebook/lib/python3.7/site-packages/traitlets/traitlets.py in __call__(self, *args, **kwargs)
    905         """Pass `*args` and `**kwargs` to the handler's function if it exists."""
    906         if hasattr(self, 'func'):
--> 907             return self.func(*args, **kwargs)
    908         else:
    909             return self._init_call(*args, **kwargs)

/srv/conda/envs/notebook/lib/python3.7/site-packages/ipywidgets/widgets/widget_selection.py in _validate_index(self, proposal)
    350             return proposal.value
    351         else:
--> 352             raise TraitError('Invalid selection: index out of bounds')
    353 
    354     @observe('index')

TraitError: Invalid selection: index out of bounds

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Yes, thanks!

@jmwright I just released 2.0.0. It now automatically selects the last element for replays to ensure the full result is shown first. I guess we can close this ticket now?

I misunderstood what the sliders were for in that gif.

The way I had it in the FreeCAD module it would set the parameters and re-execute using CQGI. I think I had plain number fields, and it takes a bit for larger models to be refreshed after changing the parameters, but it worked pretty well.

@villares No worries and thanks for using jupyter-cadquery

The process to view a cadquery object is the following:

  • The user creates a cadquery object
  • Then jupyter cadquery tesselates the object (i.e. creates a mesh of each object)
  • This mesh is used to create a pythreejs Geometry
  • And this geometry is rendered in pythreejs.

This means the cad view is completely decoupled from the cadquery object and as such I don’t see an easy way to use sliders to change the underlying cadquery object (if this is what you would like to achieve)

Do you see the whole cad view including buttons, part tree, …? If so, the part tree is a tabbed view. If you click on “Clipping”, you’ll see the clipping dialog, if you click on “Tree” again, you’ll see the Part tree again.

Btw. you can also double click on parts in the cad view and see some info in the box below “Tree/Clipping”

@bernhard-42 Thanks for the info, it helps me understand the intended workflow better.

There are sliders shown in this animated gif, and that’s a really cool (and useful) feature. https://github.com/bernhard-42/jupyter-cadquery/blob/master/screenshots/clipping.gif

I can’t figure out how to access those though.

Tagging @villares on this too as the information above will hopefully be helpful.