GithubHelp home page GithubHelp logo

orbingol / nurbs-python Goto Github PK

View Code? Open in Web Editor NEW
572.0 572.0 151.0 13.13 MB

Object-oriented pure Python B-Spline and NURBS library

Home Page: https://onurraufbingol.com/NURBS-Python/

License: MIT License

Python 98.32% Dockerfile 1.49% Shell 0.19%
bezier bspline cad computational-geometry curve geomdl geometric-modeling geometry nurbs python surface volume

nurbs-python's People

Contributors

cshorler avatar heczis avatar nodli avatar orbingol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nurbs-python's Issues

NURBS derivatives

I made a test of NURBS derivatives using a circle, I don't believe the outputs to be correct (see picture). I also note that NURBS derivatives are documented in more recent papers than the NURBS book - so perhaps this isn't expected to work.

I'll provide a test for this at the next opportunity

Manually (Tested on Linux & Windows, Python 2 & 3):

  1. Create a 7pt NURBS circle (also not convinced the 7pt construction in geomdl.shapes is correct after my back of the envelope calculation for a unit circle - it looks isosceles rather than equilateral?). Also tested with 9pt (see picture)

  2. Create derivatives

  3. Plot the results

I was expecting circles.
circles_and_first_derivatives

Wrong exception wording for Curve2D

import geomdl.BSpline
curve = geomdl.BSpline.Curve2D()
curve.ctrlpts = [(1,2,3)]

----> ValueError: ERROR: Please input 3D coordinates

Don't you mean "Please input 2D coordinates?"

Implement Knot Insertion

Knot insertion is one of the fundamental geometric algorithms stated in The NURBS Book. The major advantages of the knot insertion operation are;

  • Splitting (subdividing) curves and surfaces
  • Interactive design (adding control points to make shape control more flexible)

Let's start implementing the knot Insertion algorithms (A5.1 for curves, A5.3 for surfaces).

CAD File import for Blender

Hi orbingol,

Commercial 3D programs like Cinema 4D and Maya can import, tessellate and render CAD data. Unfortunately Blender does not have this possibility. But I believe that this will be of great importance for this software. That's why I'm trying to figure out how something could be made possible in this direction. Thereby I came across Nurbs Python.

Do you believe your Nurbs Python library could make it possible for Blender to read and tessellate CAD files in order to create high-quality renderings?

Thank you very much for your time
Sebastian

Calculate cubic splines that best fit the nurbs curves to a tolerance

This one is more of a challenge (but worth doing).

It would mean that DXF (which contains nurbs) to SVG (which only does cubic splines) will work perfectly.

(BTW, nurbs are an annoyance in CADCAM; cubic splines are smooth enough for all purposes, because you can make them as short as you need to, the GUIs are no longer restricted to moving one control point at a time, and any CAM process needs to turn everything to flat segments before it can work -- you don't get splines in G-code.)

Improve evaluators module API and its documentation

evaluators module API looks very complicated and probably misunderstood. There are also improper uses of keyword arguments. The complicated structure of the API should be fixed and its documentation should be improved.

VTK renders are very noisy compared to MPL renders

Describe the bug
The VisVTK Visualisation module renders partly deformed surfaces. VisMPL module works as expected.

To Reproduce
Steps to reproduce the behavior:

  1. fit a point cloud.
  2. set delta to 0.02
  3. render using VTK
  4. See error

Expected Behavior
The VisVTK module should render the surfaces as they are.

Configuration:

  • OS: Ubuntu 18.10
  • Python distribution: Anaconda
  • Python version: 3.6.8
  • geomdl install source: Anaconda
  • geomdl version/branch: 5.0b4

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.
mesh2_mpl
mesh2_vtk
mpl
vtk

Utilities - Wrong number of knots

function generate_knot_vector may generate wrong number of knots

Original code:
# Middle knots
knot_vector += [mid_knot for mid_knot in frange(0, 1, spacing)]

number of Middle knots can be one more than expected. A quick fix:
# Middle knots
knot_vector += [mid_knot for mid_knot in frange(0, 0.99999999999, spacing)]

Getters and setters related to control points should use the new Manager classes

Currently, ctrlpts, ctrlptsw and weights properties accept a list of points (or values) and the order of the points are described in the documentation. Addition of B-Spline and NURBS volume geometry type makes setting of the control points a little bit confusing. The users do not need to know the internal structure of the library and it also serves to the purpose of geomdl: keeping the things as simple as possible.

As a result, it would be a good idea to replace the get-set values of the corresponding properties with a point manager class under control_points module. This is going to result in an API change starting from v5.3.0 but it will make control points setting less confusing, especially for Surface and Volume users.

Vertex data faulty conditional?

Describe the bug
When I am importing my data using the NURBS module, the data setter in elements.py appears to unnecessarily give the following error:

raise ValueError("Vertex can only store 3 components")

To Reproduce
Steps to reproduce the behavior:

  1. Put the "nurb_vertex_bug" and data file into the same directory.
  2. Modify the path to the data file in the import function in the "nurb_vertex_bug" file
  3. Execute "nurb_vertex_bug"

Expected Behavior
I expected a successful rendering of a NURBS surface corresponding to this data. Here are the steps I've already taken to try to resolve this issue:

-Changed type of input data (tried both 2D list and list of tuples)
-Verified using a for loop that each element of this list does in fact have length of 3
-Looked at the source code for possible clues as to what is causing the ValueError

Configuration:

  • OS: Ubuntu 16.04
  • Python distribution: Default
  • Python version: 2.7.12
  • geomdl install source: Pip install
  • geomdl version/branch: 5.1.2

nurb_bug.zip

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.

Additional Details (Optional)
I am using a lot of data, so maybe it has to do with the way my data is formatted? It just seems like the error that is being reported does not match what is actually causing the error to be thrown.

NURBS is not correct when applied a weight vector. if the weight vector is not all 1.

from geomdl import NURBS
from geomdl import compatibility as compat

crv = NURBS.Curve()
p_ctrlpts = [[1, 1], [2, 1], [3, 0], [4, 4], [3, 9], [10, 2]]
p_weight = [1, 1, 1, 1, 3, 1]

t_ctrlptsw = compat.combine_ctrlpts_weights(p_ctrlpts, p_weight)

after, Weight = compat.separate_ctrlpts_weights(t_ctrlptsw)

crv.degree = 2
crv.ctrlpts = t_ctrlptsw
crv.knotvector = [0, 0, 0, 1, 2.5, 3, 5, 5, 5]
crv.delta = 0.005
points = crv.evalpts

from geomdl.visualization import VisMPL
crv.vis = VisMPL.VisCurve2D()
crv.render()
#the result was the coordinates change of the control points. But I just change the weight, why?

Can't Import Fitting Module

Describe the bug
A clear and concise description of what the bug is.

After installing NURBS-Python using pip, when I try to import the "fitting" module, I get an error saying "cannot import name fitting"

To Reproduce
Steps to reproduce the behavior:

  1. Execute "pip install geomdl" install command
  2. Copy or download the following example from NURBS-Python_Examples: NURBS-Python_Examples/fitting/interpolation/global_surface.py
  3. Run the File

Expected Behavior
I expected the file to run with a visualization of the approximated surface

Configuration:

  • OS: Ubuntu 16.04
  • Python distribution: OS default
  • Python version: 2.7.12
  • geomdl install source: "pip install geomdl" command
  • geomdl version/branch: 4.4.4

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.

Additional Details (Optional)
StackOverFlow says that it may be due to circular dependencies?

Implementing mesh and triangle export modes

Surface points CSV export function save_surfpts_to_csv has 5 export modes:

  • linear
  • zigzag
  • wireframe
  • triangle
  • mesh

However, triangle and mesh modes have not been implemented yet.

Add X3D import/export support

The Wikipedia definition for X3D is a royalty-free ISO standard for declaratively representing 3D computer graphics. It is possible to find more details on the website www.web3d.org

X3D contains a lot of elements and I believe, for starters, it would be good to include support for the following elements:

  • NurbsCurve
  • NurbsCurve2D
  • NurbsPatchSurface
  • NurbsTrimmedSurface

Questions about Derivative Evaluation

Describe the bug
Similar as before, this may be more of a question (I'm not sure how to change the label). I'm needing to evaluate the partial derivative of a surface at a given point. When I use the "derivatives" evaluator for surface, the output I get doesn't appear to match the form shown in The NURBS Book and the values do not match what I'm expecting. Any help would be greatly appreciated!

To Reproduce
Steps to reproduce the behavior:

  1. Create a test surface (mine is too large to share) and call the derivatives evaluator. For the "order" argument, I used 2.
  2. The output produces a 3-dimensional list of numbers instead of a 2-dimensional list.

Expected Behavior
A two dimensional list of partial derivatives. I'm confused as to why I'm getting a 3-dimensional list. The NURBS book shows that the list should be 2-dimensional.

Configuration:

  • OS: Ubuntu 16.04
  • Python distribution: OS default
  • Python version: 2.7.12
  • geomdl install source:
  • geomdl version/branch: 5.1.2
    derivative2
    derivative4

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.

Additional Details (Optional)
Add any other context about the problem here.

Dimension issues inside read_ctrlpts

If the number of points along U and V are not the same, then this line produce an 'out-of-range' error:
ctrlpts_v.append(self._mCtrlPts[i + (j * self._mCtrlPts_sizeV)])

I think it should be j + (i * self._mCtrlPts_sizeV)

Update degree elevation and reduction functions

As of geomdl v5.0.x, control points computation parts of the degree elevation and reduction algorithms are implemented in helpers module and they are working. On the other hand, the API call responsible for degree elevation and reduction (operations.degree_operations ) is still not working.

operations.degree_operations function should be updated with the correct algorithms and should be tested with B-spline and NURBS geometries.

Linearize curves and surfaces to a tolerance

It looks like curvepts is made by proceeding at a sample rate of _delta from 0 to 1 proportionally along the whole length of the spline.

For use in CAM we want the geometry subdivided only as far as necessary that the the approximation fits the the curve within the margin of a tolerance value. Often we will set this to the tolerance of the CNC machine, but we don't want to overdo it, because the controllers tend to choke on too many close together points.

`ZeroDivisionError` on large bézier knotvectors

Describe the bug
A ZeroDivisionError occurs with the message "float division by zero".

To Reproduce
Steps to reproduce the behavior:
Run the following example:

from geomdl import BSpline
from geomdl import utilities
from geomdl.visualization import VisMPL

curve = BSpline.Curve()
curve.degree = 3
curve.ctrlpts = [[0, 0], [1, 1], [2, 0], [3, 1], [4, 0], [5, 1]]
curve.knotvector = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
curve.delta = 0.01
curve.vis = VisMPL.VisCurve2D()
curve.render()

Expected Behavior
This should yield a Bézier curve, right?

Configuration:

  • OS: macOS 10.14.5
  • Python distribution: brew
  • Python version: 3.7.3 64-bit
  • geomdl install source: PyPI
  • geomdl version/branch: 5.2.7

Additional Details (Optional)
The code above works, if we only define three ctrlpts and a knotvector of length 6:

curve.ctrlpts = [[0, 0], [1, 1], [2, 0]]
curve.knotvector = [0, 0, 0, 1, 1, 1]

Normal vectors to curves are incorrect.

Normals to curves are incorrect.

I've created a patch for this - basically the assumption in _operations.py under normal_curve_single() is false: # 2nd derivative of the curve gives the normal

The patch only addresses this one case, but I'm sure the bug occurs elsewhere in the library. Happy to provide what I've done.

Unpatched output, plotting the normals at 3 points on a curve:
image

Patched output, plotting the normals at the same 3 points on the same curve:
image

Implement obj export

NURBS-Python v3.0 comes with CSV export functionality with different meshing capabilities. This functionality developed for importing point cloud sets to Paraview or other compatible software.

For the release of NURBS-Python v3.1, exporting surfaces to OBJ files has been planned.

Add more keypress events to VTK visualization module

The following list is available directly from the default vtkInteractorStyle used:

  • e: exit the application
  • p: pick object (hover the mouse and then press to pick)
  • f: fly to point (click somewhere in the window and press to fly)
  • r: reset the camera
  • s and w: switch between solid and wireframe modes

It would be nice to add option to change visibility of some other elements, such as control points, objects, etc.

Slicing

I have a piece of code which calculates control points for an arbitrary arc using vector calculus. One possible way to achieve outputs is to pre-calculate nice fraction angular sector weights (e.g. 1/2). Only calculating the final weight explicitly, possibly this isn't a good approach for distributing the error - but what's notable is slicing is not supported, so you have to workaround this - making the code slightly less concise than it could be.

The example is for weights, but I imagine the problem / feature need is evident on all attribute lists of curves and surfaces.

I've started working on a possible way to handle this the branch below:
https://github.com/cshorler/NURBS-Python/tree/slicing_and_nurbs_derivatives

a line seems useless

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected Behavior
A clear and concise description of what you expected to happen.

Configuration:

  • OS: [e.g. Windows 10, Ubuntu 18.10]
  • Python distribution: [e.g. OS default, python.org, Anaconda]
  • Python version:
  • geomdl install source: GitHub / PyPI / Anaconda
  • geomdl version/branch: 5.9.2

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.

Additional Details (Optional)
in fittings.py function compute_params_curve, when calculate the chord length, at line 441, the last element of cds is assigned -1

cds is a list of chord length, it shouldn't be assigned to a fixed value, if needed, the first element of cds can be assigned 0, other elements should not be a fixed value

and it's length should be equal to points length, not plus 1 (in line 440)

after some review of the literature book and the code, I think it's useless. Maybe you developer have some extra idea, I'll be very happy to see if you provide detailed introduction of your idea.

Add more tests

The derivative methods are not covered with the existing tests.

Edit: Some other methods are needed to be covered by the unit tests.

Cannot export evalpts

Hey buddy,

I assume you have a bug trying to export the evalpts, in the function _export_txt you have the following:

    else:
        # B-spline or NURBS?
        try:
            ctrlpts = obj.ctrlptsw
        except AttributeError:
            ctrlpts = obj.ctrlpts
        # Loop through points
        for pt in ctrlpts:
            line = sep.join(str(c) for c in pt) + "\n"
            fp.write(line)

I modified the lines so that the function reads the evalpts to write instead the control points. Otherwise you will write the ctrlpts always.

    else:
        # B-spline or NURBS?
        try:
            ctrlpts = obj.ctrlptsw
        except AttributeError:
            evalpts = obj.evalpts 
            ctrlpts = obj.ctrlpts
        # Loop through points
        for pt in evalpts: # instead ctrlpts
            line = sep.join(str(c) for c in pt) + "\n"
            fp.write(line)

Am I wrong?

Improve performance of the visualization modules

Visualization modules in NURBS-Python were never intended to be a part of the core library. In the beginning, they were added to visually debug the evaluation results in a faster way. Therefore, they weren't designed to be efficient but just visualize whatever sent to them from the render method. When needed, they received some upgrades and new features and these are are mostly connected to the core library updates.

As of geomdl v5.2, it is very easy to say that all visualization modules are now a part of the core library but due to the preliminary idea in their design, they seem to be now a little bit outdated and more importantly, they work slow. Therefore, they need to be improved.

This issue is opened due to some problems encountered while implementing the feature request #46 and it would be a good idea to revise the visualization system a little bit without changing its API. As a result, this issue extends #46.

The following changes are proposed for now:

  1. At every call, render method resets the plot cache in the visualization module and transfers the point data again to the visualization module. The visualization module converts all these into its internal data structure and as a result, visualization gets slow. There can be a conditional check in the render method of the geometry class to use existing plot data in the vis module if there are no changes in the geometry data. In addition, it is always good to have an optional argument, such as force, to force re-transfer of the point data to the vis module.
  2. The visualization modules can cache the figure data for faster viewing. This cache should be connected to the changes and the force parameter in the render method of the geometry class.
  3. Add key press events to change visibility of the objects, if possible

Join in the NURBS workbench for Freecad

Hi ! fist of all congratulation for your work, I star to study your cod and The NURBS Book ! What do you think about to implement your cod in the Silk project?. Silk (https://edwardvmills.github.io/Silk/) have the vantage from GUI and Freecad tool.

I wish do a code to make Isogeometric Analysis (IGA) and will be amazing work together. IGA employs NURBS for integrate Partial Differential Equation. The plan is:

  1. Advantage from a GUI in Silk workbench for Freecad (https://forum.freecadweb.org/viewtopic.php?f=22&t=23243)
  2. Implement your function for build a grate model NURBS code, I'm working for performs a boolean operations on solids represented by NURBS
  3. Develop a PDE Solver (something like this http://rafavzqz.github.io/geopdes/)

Sphere import from rhino

Im new to geomdl, facing some problems with importing primitives like e.g. a sphere.

The sphere is displayed in Rhino correctly.
However, after converting the 3dm file with on2sjon, and importing again with geomdl, the gemeotry is significantly different from what I would expect:

import os
from geomdl import NURBS
from geomdl import exchange
from geomdl.visualization import VisMPL as vis

Import surfaces

surfs = exchange.import_json("sph_r_0p5m.json")

Plot the control point grid and the evaluated surface

surfs[0].sample_size = 100
surfs[0].delta=0.05
surfs[0].vis = vis.VisSurface()
surfs[0].render()

geometry.zip

Im grateful for any help, thanks!
rhino
geomdl

Add support for more visualization libraries

NURBS-Python provides an optional geomdl.visualization component for direct visualization of the curves and surfaces generated by the library. Currently, there is only one visualization module VisMPL which uses Matplotlib for generating the plots.

It could be a good idea to add more visualization options which use different libraries, such as Plotly or OpenGL.

Problem: evaluate the Hessian matrix in the XYZ coordinate

Hi,

I'm a PhD student in mechanical engineering so my questions may appear trivial to you. But from my experience with the NURBS library, I couldn't get the Hessian matrix of a curve with respect to the XYZ coordinate. It appears to me that the NURBS evaluates the derivative in the arc-length parameterized coordinate.

For example, I used NURBS to reconstruct a circle and the 1st derivative at one point seems to be the tangent vector and then the 2nd derivative is the normal vector and the 3rd derivative seems to be the tangent vector in the "negative" direction. However, the Hessian matrix I want for the circle should be [2 0;0 2] (f: x^2+y^2 = R -> gradient: [2x;2y] -> Hessian: [2 0;0 2];

I wonder if there is a way that I can evaluate the Hessian matrix with respect to the XYZ coordinate with your NURBS library?

Thank you for your great contribution and help.

Compute the derivative (hodograph) shape

With PR #33 derivatives_ctrlpts method for computing the control points of the shape (curve and surface) derivative is added to BSpline class.

I think it would be a better idea to compute the derivative shape with the control points and knot vectors together, very much similar to how decompose method does.

Confusing getters and setters in NURBS class

It seems that getter-setter structure for control points of NURBS class is confusing to some users. I was trying to follow the notation in The NURBS Book; for B-Splines control points are represented with P and for NURBS Pw. Some users think that control points setter is for setting P and weights setter (which doesn't exist in the current version) is for setting w.

The control points getters and setters will be updated as follows:

  • ctrlpts: getter will return the unweighted control points P and setter will only change the control points but not weights. If there are no control points set prior to calling setter function, then all control points will be saved with weights = 1.
  • ctrlptsw: getter and setter will directly work with weighted control points Pw.
  • ctrlpts2d: same as ctrlpts but the array will be 2D, representing [u][v] directions
  • ctrlptsw2d: same as ctrlptsw
  • weights: getter will return weights and setter will only update the weights of the Pw

There will be single variable for storing control points NURBS._control_points and it will store Pw (we don't want to break up the existing code) and all other variables will be generated on-the-fly and saved to the _cache dictionary.

Some of these getters and setters already in the code but they might be operating differently from the instructions above.

Typing Module Not Found

Describe the bug
After installing NURBS-Python using pip, when I try to import the "fitting" module, I get an error saying

" from geomdl import fitting
from typing import Any, Sequence, List, Tuple
ImportError: No module named typing"

To Reproduce
Steps to reproduce the behavior:

  1. Execute "pip install geomdl" install command

  2. Copy or download the following example from NURBS-Python_Examples: NURBS-Python_Examples/fitting/interpolation/global_surface.py

  3. Run the File

Expected Behavior
I expected the file to run with a visualization of the approximated surface.

Configuration:

  • OS: Ubuntu 16.04
  • Python distribution: OS default
  • Python version: 2.7.12
  • geomdl install source: "pip install geomdl" command
  • geomdl version/branch: 5.0.0

Screenshots (Optional)
If applicable, add screenshots to help explain your problem.

Additional Details (Optional)
Website says that NURBS is compatible with python 2.7.x and 3.4.x. I'm not able to find "Typing" module under python 2 documentation, so will I need to upgrade python?

Any Pure-Python CSG/CAD lib good interoperability ?

Hello @orbingol and others !

Thanks very much for your work, hope to contribute !

I'm building a pure-python serverless (AWS Lambda) STL object generation tool for creative coding, and I was wondering if you knew if NURBS is intended to do CSG operations or if there is a good library that is also pure-python and works well with NURBS-Python.

Thanks again,
Elias

ray.intersect tolerance is unrealistic

Describe the bug
The default tolerance (tol=) of the ray.intersect is set smaller than the machine epsilon. Leading to RayIntersection.SKEW results (sometimes incorrectly)

To Reproduce
test case in my fork branch and workaround:
https://github.com/cshorler/NURBS-Python/tree/relax_ray_intersect_tolerance
(need to rebase this on master if PR is required before integrating other PR - happy to do either).

Expected Behavior
My quick fix was to change the default tolerance to be a multiple of machine epsilon after investigating a few likely causes in linalg module. In the long term, I think the correct thing to do would be change the implementation to improve the accuracy.

Configuration:

  • OS: Tested on Windows 10 (Python 2.7), Linux openSUSE (Python 3.6)
  • Python distribution:. Anaconda & OS default
  • Python version: see above
  • geomdl install source: GitHub
  • geomdl version/branch: master, and others

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.