Giter VIP home page Giter VIP logo

freecad-enhancement-proposals's Introduction

Your own 3D parametric modeler

WebsiteDocumentationForumBug trackerGit repositoryBlog

Release Crowdin Liberapay

Overview

  • Freedom to build what you want FreeCAD is an open-source parametric 3D modeler made primarily to design real-life objects of any size. Parametric modeling allows you to easily modify your design by going back into your model history to change its parameters.

  • Create 3D from 2D and back FreeCAD lets you to sketch geometry constrained 2D shapes and use them as a base to build other objects. It contains many components to adjust dimensions or extract design details from 3D models to create high quality production-ready drawings.

  • Designed for your needs FreeCAD is designed to fit a wide range of uses including product design, mechanical engineering and architecture, whether you are a hobbyist, programmer, experienced CAD user, student or teacher.

  • Cross platform FreeCAD runs on Windows, macOS and Linux operating systems.

  • Underlying technology

    • OpenCASCADE A powerful geometry kernel, the most important component of FreeCAD
    • Coin3D library Open Inventor-compliant 3D scene representation model
    • Python FreeCAD offers a broad Python API
    • Qt Graphical user interface built with Qt

Installing

Precompiled packages for stable releases are available for Windows, macOS and Linux on the Releases page.

On most Linux distributions, FreeCAD is also directly installable from the software center application.

For development releases check the weekly-builds page.

Other options are described at the wiki Download page.

Compiling

Compiling FreeCAD requires installation of several libraries and their development files such as OCCT (Open Cascade), Coin and Qt, listed in the pages below. Once this is done, FreeCAD can be compiled with CMake. On Windows, these libraries are bundled and offered by the FreeCAD team in a convenient package. On Linux, they are usually found in your distribution's repositories, and on macOS and other platforms, you will usually have to compile them yourself.

The pages below contain up-to-date build instructions:

Reporting Issues

To report an issue please:

  • First post to forum to verify the issue;
  • Link forum thread to bug tracker ticket and vice-a-versa;
  • Use the most updated stable or development versions of FreeCAD;
  • Post version info from eg. Help > About FreeCAD > Copy to clipboard;
  • Post a Step-By-Step explanation on how to recreate the issue;
  • Upload an example file to demonstrate problem.

For more detail see:

The FPA offers developers the opportunity to apply for a grant to work on projects of their choosing. Check jobs and funding to know more.

Usage & Getting help

The FreeCAD wiki contains documentation on general FreeCAD usage, Python scripting, and development. These pages might help you get started:

The FreeCAD forum is also a great place to find help and solve specific problems you might encounter when learning to use FreeCAD.

This project receives generous infrastructure support from and KiCad Services Corp.

freecad-enhancement-proposals's People

Contributors

kkremitzki avatar looooo avatar

Stargazers

 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

Forkers

looooo vocx-fc

freecad-enhancement-proposals's Issues

Workflow

Now that the template is merged I'd like to discuss the workflow.
I envision it working something like this;

Fork this repo
Clone the repo locally
Create a local branch
Copy and rename the template
Fill in the template (maybe partially)
Commit and push to forked repo
Open an issue here with a link to the forked repo and a link to mantis if applicable
Refine the proposal through discussions in the issue, pushing commits to the forked repo or accepting pull requests to the fork
Make a pull request against master here
Further refine the pull request
Merge after review (here the pull requester should not be the one to merge)
Implement the proposal
Close the issue here and mantis if applicable

After discussion maybe I can make a readme.md for the master branch.
The intent is not to make this too corporate, but maybe for these type of intrusive change we need some structure.

Please don't hold back on criticism.

Cannot update freecad-common ( 2:0.19+dfsg1~202103010028~ubuntu20.04.1) on Linux Mint

Hello,

I cannot update the last version of freecad-common ( 2:0.19+dfsg1~202103010028~ubuntu20.04.1), due to QtCore.py conflict .
I did not have any problem usually...

Message (in french :-) ):
E: /var/cache/apt/archives/freecad-common_2%3a0.19+dfsg1~202103010028~ubuntu20.04.1_all.deb: tentative de remplacement de « /usr/share/freecad/Ext/PySide/QtCore.py », qui appartient aussi au paquet freecad-runtime 2:0.18.4+dfsg2~202007252144~ubuntu20.04.1

Translation:
E: /var/cache/apt/archives/freecad-common_2%3a0.19+dfsg1~202103010028~ubuntu20.04.1_all.deb:trying to replace « /usr/share/freecad/Ext/PySide/QtCore.py », which also belong to the package freecad-runtime 2:0.18.4+dfsg2~202007252144~ubuntu20.04.1

image

[FEP02] Enforcing PEP8 rules (pep8-naming, flake8-import-order)

FEP02
Title Enforcing PEP8 rules (flake8, flake8-import-order, pep8-naming)
Status Draft
Author(s) Vanuan
Created Aug 28, 2020
Updated
Issue
Discussion https://forum.freecadweb.org/viewtopic.php?t=37405
Implementation (Partial) FreeCAD/FreeCAD#3772

Abstract

This is a proposal to enforce PEP8 rules gradually, rule by rule, workbench by workbench using the flake8 tool.

This proposal focuses primarily on fixing the following styling errors:

  • pep8-naming: N801,N802,N803,N804,N805,N806,N807,N811,N812,N813,N814,N815,N816,N8017
  • flake8-import-order: I100, I101, I201, I202

But the approach could be extended to add more PEP8 rules.

Motivation

When reviewing Python code it's important that the coding style is consistent. If it's inconsistent, reviewer spend time teaching contributors about the coding style. Contributors, OTOH are frustrated that there's an apparent discretion that reviewers apply when reviewing the code. Different workbenches have different rules, e.g. Path/CAM, so even reviewers can't always agree on the rules a specific codebase should follow. This takes unneeded discussions, effort and energy that would've better be spent elsewhere.

The problem above means there should be some objective set of rules enforced by an automated system. Thankfully, Python community already though about these issues and prepared PEP8 - a style guide for Python code and a corresponding tool to enforce them - Flake8.

Specification

The rules are described pretty well in both the original PEP8 document and in the dedicated packages: flake8-import-order and pep8-naming.

But let's duplicate those:

Imports

I100: Your import statements are in the wrong order.
I101: The names in your from import are in the wrong order.
I201: Missing newline between import groups.
I202: Additional newline in a group of imports.

Naming

N801 | class names should use CapWords convention
N802 | function name should be lowercase
N803 | argument name should be lowercase
N804 | first argument of a classmethod should be named ‘cls’
N805 | first argument of a method should be named ‘self’
N806 | variable in function should be lowercase
N807 | function name should not start and end with ‘__’
N811 | constant imported as non constant
N812 | lowercase imported as non lowercase
N813 | camelcase imported as lowercase
N814 | camelcase imported as constant
N815 | mixedCase variable in class scope
N816 | mixedCase variable in global scope
N817 | camelcase imported as acronym

Rationale

Flake8 is a de-facto standard for style guide verification, so that choice is quite straightforward.

Alternatives

No alternatives I'm aware of. There's a codespell tool but that focuses on the proper use of English (automating spelling error correction).

Backwards Compatibility

To preserve compatibility, when renaming we should add a proxy name and mark it as deprecated and put a version in which it was deprecated. After a new version of FreeCAD is released, the deprecated name may be safely removed.

To make flake8 happy, we add the following comment:

# noqa: N802

Where N802 is a name of an error we wish to ignore (until a new version of FreeCAD is released after which we can remove the ignore).

Sample Implementation

First, install the packages: python3 -m pip install flake8 flake8-import-order pep8-naming flake8-pyi

Add the .flake8 config file at the root of the project:

[flake8]
application-import-names = FreeCAD,FreeCADGui,Draft,Part,draftutils, DraftGeomUtils, DraftVecUtils
import-order-style = google
select = N801,N802,N803,N804,N805,N806,N807,N811,N812,N813,N814,N815,N816,N8017,E303,I201,I202,I101,I100
max-line-length = 160
filename = */src/Mod/Draft/draftguitools/gui_snapper.py

And run this command: flake8.

By changing the filename and select options we can configure the scope of the rule enforcement and improve the enforcement coverage file by file, rule by rule, workbench by workbench.

FreeCAD already uses Travis CI to run C++ tests. Having an additional step of Python-specific tests should not make it slower as it takes several seconds rather than minutes. If TravisCI is an issue, we can try CircleCI or other tools that give some free quota to improve the running time.

Related forum threads and wiki pages:

FAQ

Q: Is it compatible with rules we have in XXX workbench?
A: The goal of this proposal is to enforce the PEP-8 rules we choose across all the workbenches. As long as these rules are supported by flake8, yes

Q: What if I don't like the rule applied in my specific case?
A: You can add the line that violates the rule to ignore it (# noqa: XXX) or you could disable it in the whole file. Let's discuss on a case by case basis.

Q: But this hurts my creativity, I can't express myself in my unique style!
A: FreeCAD is a collaborative project, so it's important that the coding style is consistent even if some contributors don't like it. You read the code much more often than you write it, so it takes some time to get used to. Moreover, once you learn this coding style, you can contribute to any Python project as PEP8 rules are a de-facto standard in the Python community.

Q: But can this be not enforced by the tool? I promise that I won't violate any rules!
A: Unfortunately, people make mistakes. Even in a good faith, contributors can't be trusted. Tools are objective and even if they fail, they fail consistently, so issues can be fixed in bulk.

Copyright

All FEPs are explicitly CC0 1.0 Universal.

Wiki and Projects

Could you please enable Wiki and Projects?

I think at this stage non-formal project and task tracking might work better.

[FEP01] Formalising the DocumentObject model and the property system

FEP01
Title Formalising the DocumentObject model and the property system
Status Draft
Author(s) Vanuan
Created Aug 28, 2020
Updated
Issue
Discussion https://forum.freecadweb.org/viewtopic.php?f=10&t=49619
Implementation NA

Abstract

Keeping up to date with the Object API, verifying its usage correctness and being productive while using it in the IDE needs changing the way we define and document properties. This proposal suggests a way to move to the static definition of properties and object types. The primary focus is on the Python API, keeping in mind finding a way to integrate it into C++ workflow.

Motivation

Part 1

Being interested in CI to improve overall quality and frustrated with a lot of seemingly easy preventable Python exceptions, I've started looking into how python tooling can help to find bugs before users report them. Taking a look into the pylint proposal and doing some research, I've came to conclusion that static analysis tools mainly focus on the type correctness (keeping track of None values and object attributes and methods).

Among static analysis tools the most advanced ones are pyright and mypy. Pyright is used in the Microsoft's Python extension for VSCode (read the article) and mypy is used for CI scripting, to catch bugs before they're merged.

While trying to integrate it (see PR) I soon found that the DocumentObject class which is a return type of a FreeCAD.ActiveDocument.addObject method has a type system which is not exposed to static analysis tools. In fact, it is completely hidden from any sort of static analysis. The type on an object can only be inferred in runtime.

Part 2

Being interested in how different object types fit together and how their properties work, I started reading wiki. E.g. Arch Wall. Soon I've came across the Object API page which pointed me to the autogenerated documentation. Finding a corresponding page for ArchWall I was baffled that it doesn't list any of the properties listed on the Wiki page.

Digging further, I found this is generated by a combination of sphinx and Doxygen. Those tools only understand the Python and C++ documentation syntax. They cannot look into the dynamic types and property system that is the core of FreeCAD.

So, there are multiple documentation sources. Some of them are manual, some are automatic. There's a need for consolidation of the Object API into a cohesive system driven by a single source of truth.

Thinking of a way to implement it, I've came to conclusion that you need to create the document with all the possible object types and their properties and iterate though them to build documentation. This approach is very expensive as you need to build the whole FreeCAD first, and run it on some performant server. Besides writing a script to generate the docs in the first place.

Instead of runtime type inference, it seems more reasonable to define types statically and generate the code which adds them in runtime. As it is fast, doesn't require C++ toolchain, so can be integrated into automated documentation generation CI quite cheaply.

Current C++ to Python XML bindings already do quite a good job to define Objects statically. But they are not enough. There needs to be a Python counterpart as the bulk of objects are defined using the App::FeaturePython Scripted Objects.

Specification

YAML-based properties in Python

Here's an attempt of capturing the definition of properties added using the addProperty method.

Arch.Structure is given as an example.

Structure:
  parent: "Component"
  properties:
    Tool:
        type: "App::PropertyLink"
        desc: "An optional extrusion path for this element"
    Length:
        type: "App::PropertyLength"
        desc: "The length of this element, if not based on a profile"
    Width:
        type: "App::PropertyLength"
        desc: "The width of this element, if not based on a profile"
    Height:
        type: "App::PropertyLength"
        desc: "The height or extrusion depth of this element. Keep 0 for automatic"
    Normal:
        type: "App::PropertyVector"
        desc: "The normal extrusion direction of this object (keep (0,0,0) for automatic normal)"
    Nodes:
        type: "App::PropertyVectorList"
        desc: "The structural nodes of this element"
    Profile:
        type: "App::PropertyString"
        desc: "A description of the standard profile this element is based upon"
    NodesOffset:
        type: "App::PropertyDistance"
        desc: "Offset distance between the centerline and the nodes line"
    FaceMaker
        type: "App::PropertyEnumeration"
        desc: "The facemaker type to use to build the profile of this object",
        default: ["None","Simple","Cheese","Bullseye"]

This already allows to generate the following class that allows you to add type information in runtime:

class Structure(Component):
    Tool        = staticmethod(lambda: ("App::PropertyLink",        "An optional extrusion path for this element"))
    Length      = staticmethod(lambda: ("App::PropertyLength",      "The length of this element, if not based on a profile"))
    Width       = staticmethod(lambda: ("App::PropertyLength",      "The width of this element, if not based on a profile"))
    Height      = staticmethod(lambda: ("App::PropertyLength",      "The height or extrusion depth of this element. Keep 0 for automatic"))
    Normal      = staticmethod(lambda: ("App::PropertyVector",      "The normal extrusion direction of this object (keep (0,0,0) for automatic normal)"))
    Nodes       = staticmethod(lambda: ("App::PropertyVectorList",  "The structural nodes of this element"))
    Profile     = staticmethod(lambda: ("App::PropertyString",      "A description of the standard profile this element is based upon"))
    NodesOffset = staticmethod(lambda: ("App::PropertyDistance",    "Offset distance between the centerline and the nodes line"))
    FaceMaker   = staticmethod(lambda: ("App::PropertyEnumeration", "The facemaker type to use to build the profile of this object", ["None","Simple","Cheese","Bullseye"]))

And the corresponding class that adds the static python type:

from typing import List, cast

class StructureType:
    @property
    def FaceMaker(self) -> Enumeration:
        """The facemaker type to use to build the profile of this object"""
        ...
    @property
    def Tool(self) -> Link:
        """An optional extrusion path for this element"""
        ...
    @property
    def Width() -> Length:
        """The width of this element, if not based on a profile"""
        ...
    @property
    def Length() -> Length:
        """The length of this element, if not based on a profile"""
        ...
    @property
    def Height() -> Length:
        """The height or extrusion depth of this element. Keep 0 for automatic"""
        ...
    @property
    def Normal() -> Vector:
        """The normal extrusion direction of this object (keep (0,0,0) for automatic normal)"""
        ...
    @property
    def Nodes() -> List[Vector]:
        """The structural nodes of this element"""
        ...
    @property
    def NodesOffset() -> Distance:
        """Offset distance between the centerline and the nodes line"""
        ...

Rationale

XML and JSON might be to verbose for this task. YAML appears to be more human friendly.

YAML could be used to generate C++ XML bindings as well. It would need to be enriched with C++ and Python imports/headers to reference dependencies.

So that there would be a single source of truth of objects defined in C++ and Python.

Alternatives

Alternatively, the current XML schema needs to be enriched with Python types. But it would mean the existing generator needs to be changed, so there's a threat of breaking backward compatibility.

Backwards Compatibility

To preserve compatibility, generated code has exactly the same behavior. In future versions we might want to change API to consolidate C++ and Python defined objects. For example, methods to manipulate objects might be divorced from the objects themselves. So that FCStd file format doesn't imply any dynamic behavior of objects but rather defines only the structure. This allows for versioning the file format separately from FreeCAD releases.

Sample Implementation

Haven't published yet, but here's a gist. Usage:

class _Structure(ArchComponent.Component, Proxy):
    "The Structure object"

    def __init__(self,obj):
        ArchComponent.Component.__init__(self,obj)
        self._setDocumentObject(Structure, obj)

Implementation:

class Proxy:
    def _setDocumentObject(self, class_, obj):
        properties = [p for p in class_.__dict__.keys() if not p.startswith("__")]
        class_name = class_.__name__
        pl = obj.PropertiesList
        for prop_name in properties:
            if not prop_name in pl:
                property_meta_func = getattr(class_, prop_name)
                assert callable(property_meta_func), "Metadata for %s.%s is not set up properly" % (class_name, prop_name)
                property_meta = property_meta_func()
                default_value = None
                if(len(property_meta) == 2):
                    prop_type_name, description = property_meta
                elif(len(property_meta) == 3):
                    prop_type_name, description, default_value = property_meta
                else:
                    raise Exception("Metadata for %s.%s is not set up properly" % (class_name, prop_name))
                obj.addProperty(prop_type_name, prop_name, class_name, QT_TRANSLATE_NOOP('App::Property', description))
                if default_value is not None:
                    setattr(obj, prop_name, default_value)

        self.Type = class_name

It relies on the Python metaprogramming by inspecting __class__.__dict__ and using DocumentObject.addProperty method to making it available to FreeCAD's runtime type system.

FAQ

Copyright

All FEPs are explicitly CC0 1.0 Universal.

Potential FEPs

  • import freecad on all platforms without sys.path modifications (discussion)
  • standardization of freecad namespace-packages
  • freecad command-line interface (standardization)
  • release numbering scheme (discussion: #1 (review))
  • alternative GUI layout AKA @ickby's layout (discussion)

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.