Fillet non possibile e crash programma dopo l'anullamento

Forum per le domande e le discussioni in Italiano
Forum rules
regole del forum e le informazioni utili

Importante: PRIMA di chiedere aiuto leggete qui!
Post Reply
DarkPhoinix
Posts: 77
Joined: Thu May 02, 2019 2:30 pm

Fillet non possibile e crash programma dopo l'anullamento

Post by DarkPhoinix »

Salve sto cercando di fare un fillet come ho già fatto sul lato opposto ma quando cerco di farlo mi dice : Resulting Shape is invalid
allora faccio "Cancel" e il programma crasha!
Qualche idea ?

OS: Windows 10 Version 2009
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.24267 +148 (Git)
Build type: Release
Branch: Branch_0.19.4

Python version: 3.8.6+
Qt version: 5.15.2
Coin version: 4.0.1
OCC version: 7.5.3
Locale: Italian/Italy (it_IT)
Attachments
fake battery.20220524-113615.FCstd
(83.08 KiB) Downloaded 60 times
DarkPhoinix
Posts: 77
Joined: Thu May 02, 2019 2:30 pm

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by DarkPhoinix »

Ho risolto ma non ho ben capito perchè non posso fare due fillet?e perchè sono obbligato a farlo nello stesso? Se ne creo un'altro il programma crasha sempre Pad002(Edgexxx)
Immagine.jpg
Immagine.jpg (234.14 KiB) Viewed 1634 times
domad
Veteran
Posts: 2051
Joined: Mon Jun 22, 2020 12:16 pm

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by domad »

DarkPhoinix wrote: Tue May 24, 2022 5:33 pm Ho risolto ma non ho ben capito perchè non posso fare due fillet?e perchè sono obbligato a farlo nello stesso? Se ne creo un'altro il programma crasha sempre Pad002(Edgexxx)
Ciao DarkPhoinix, un saluto alla Comunità!

Ho analizzato il tuo flusso riscontrando una modellazione, nel suo assieme, non proprio consona/logica, principalmente per via del raccordo dello spigolo superiore (quello che crea problemi) poichè realizzato dopo la creazione della "cava/guida" la quale da luogo alla formazione di spigoli terminali con dimensione minore di 1 mm, pertanto impostando un raccordo pari a 1 mm si creano le condizioni di non fattibilità, che in casi non rari possono provocare blocchi o addirittura crash.
Per risolvere bisogna prima creare il raccordo e poi ricavare la "cava/guida"; ma utilizzando la funzione di raccordatura (molto "delicata" in "Part Design") nel mezzo del flusso si possono creare condizioni future di "toponaming", pertanto, per un flusso ottimale sarebbe consigliabile ricavare il cilindro da rivoluzione generato da uno sketch che contiene la raccordatura.
Nel file allegato tre esempi (non i soli attuabili) di modellazione:
- Soluzione 1 buona ma sconsigliata (come sopra accennato);
- Soluzione 2 ottimale (ottenuta da rivoluzione come sopra accennato);
- Soluzione 3 ottimale realizzata utilizzando il Wb "Part".
Attachments
fake battery.20220524-113615-2.FCstd
(307.9 KiB) Downloaded 67 times
fake battery.20220524-113615-2.png
fake battery.20220524-113615-2.png (225 KiB) Viewed 1569 times
DarkPhoinix
Posts: 77
Joined: Thu May 02, 2019 2:30 pm

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by DarkPhoinix »

domad wrote: Wed May 25, 2022 1:37 pm
DarkPhoinix wrote: Tue May 24, 2022 5:33 pm Ho risolto ma non ho ben capito perchè non posso fare due fillet?e perchè sono obbligato a farlo nello stesso? Se ne creo un'altro il programma crasha sempre Pad002(Edgexxx)
Ciao DarkPhoinix, un saluto alla Comunità!

Ho analizzato il tuo flusso riscontrando una modellazione, nel suo assieme, non proprio consona/logica, principalmente per via del raccordo dello spigolo superiore (quello che crea problemi) poichè realizzato dopo la creazione della "cava/guida" la quale da luogo alla formazione di spigoli terminali con dimensione minore di 1 mm, pertanto impostando un raccordo pari a 1 mm si creano le condizioni di non fattibilità, che in casi non rari possono provocare blocchi o addirittura crash.
Per risolvere bisogna prima creare il raccordo e poi ricavare la "cava/guida"; ma utilizzando la funzione di raccordatura (molto "delicata" in "Part Design") nel mezzo del flusso si possono creare condizioni future di "toponaming", pertanto, per un flusso ottimale sarebbe consigliabile ricavare il cilindro da rivoluzione generato da uno sketch che contiene la raccordatura.
Nel file allegato tre esempi (non i soli attuabili) di modellazione:
- Soluzione 1 buona ma sconsigliata (come sopra accennato);
- Soluzione 2 ottimale (ottenuta da rivoluzione come sopra accennato);
- Soluzione 3 ottimale realizzata utilizzando il Wb "Part".
Ti ringrazio,
sei molto preparato mi spaventa un po questa cosa , perché sarà veramente difficile avvicinarsi al tuo livello! Comunque sempre meglio di usare fusion 360!
User avatar
Shalmeneser
Veteran
Posts: 9474
Joined: Wed Dec 23, 2020 12:04 am
Location: Fr

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by Shalmeneser »

PartDesign_Fillet
The user is also responsible for the integrity of his or her own model. Depending on the model, it may be impossible to perform a fillet or chamfer if the body is not big enough to support that operation. For example, it wouldn't be possible to create a 10 mm fillet if an edge is separated only 5 mm from the next surface. In that case, the maximum radius for a fillet would be 5 mm; trying to use a larger value may result in a shape that doesn't compute, or even a crash. If using the exact limit of 5 mm doesn't work, it may be possible to use a very close approximation, like 4.9999 mm, to produce the same visible result.
A fillet cannot 'eat' a face.
DarkPhoinix
Posts: 77
Joined: Thu May 02, 2019 2:30 pm

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by DarkPhoinix »

Sto guardando il tuo lavoro impressionante e la parte 3 per me è quasi impossibile capire come l'hai fatto.
Il mio progetto iniziale era un cilindro normale con quelli spacchi che non sono altro degli spazi per mettere il rame per usare un carica batterie litio per collegare batterie lipo.
ho pensato dopo per una questione estetica di modificarlo con quei fillet, è veramente così sbagliato ? perchè mi capita spesso di finire un lavoro e quindi modificarlo adesso ho paura a iniziare un progetto in un modo perchè poi andrebbe rifatto nel modo corretto da 0 se per caso dovessi modificarlo! ti dirò di più con la stampa 3d quei fillet non sono nemmeno usciti perchè l'ugello era 0,4mm.
Credo proprio che cercherò uno di quei corsi che hai accennato nell'altro post.
domad
Veteran
Posts: 2051
Joined: Mon Jun 22, 2020 12:16 pm

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by domad »

DarkPhoinix wrote: Wed May 25, 2022 7:50 pm Sto guardando il tuo lavoro impressionante e la parte 3 per me è quasi impossibile capire come l'hai fatto.
.....
Ciao DarkPhoinix, un saluto alla Comunità!
I tre esempi di modellazioni, ti assicuro, non sono assolutamente cose complesse, te ne renderai conto molto presto, in particolare la "Soluzione3" è stata eseguita utilizzando due Wb:
- Draft
- Part
con Draft sono state disegnate le polilinee chiuse (!) che hanno dato origine [funzione "Promuovi" (Upgrade)] alle superfici o facce (per ricavare gli incavi o guide);
con Part è stato inserito un cilindro, attraverso l'utilizzo dei solidi denominati "Primitive", poi sono stati creati i raccordi, quindi, sono state estruse le facce create dalle polilinee, per completare con le operazioni booleane di sottrazione o taglio ("Cut"), tutto qui (un po come si fa o si faceva se, non ricordo male, in Autocad).
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Fillet non possibile e crash programma dopo l'anullamento

Post by onekk »

Tento di aggiungere un paio di considerazioni, sperando siano comprensibili.

Premessa:

Molte volte ti trovi a dover scegliere tra "Part" e "Part Design".

"Part" è un ambiente che è alla base di FC, in quanto è una sorta di interfaccia "molto diretta" verso OCCT, hai poche funzioni di alto livello, ma in genere riesci a "portare a casa" quelo che desideri, unica eccezione notevole i filletti, ma quello è un problema di OCCT (parrebbe in via di soluzione almeno per i fallimenti macroscopici).

"Part Design" è decisamente a un più "alto livello", e quindi concettualment più complicato e "complesso", ovviamente le funzioni disponibili sono meno grezze e più raffinate.

E qui vengono le considerazioni:


La raffinatezza di "Part Design" ha un "costo" devi seguire un "flusso di lavoro" corretto e quindi devi pianificare alcune operazioni in una certa sequenza, altrimenti non riesci a realizzare un solido corretto.

Usando Part crei degli "elementi" che poi leghi e trasformi in vari modi, decisamente più grezzo, ma in genere puoi "ritornare sui tuoi passi" in modo più semplice.


Diciamo che Part è più "atomico" (nel senso che crei degli atomi per poi passare alle molecole e alle cose più complesse :-D).

Queste considerazioni sembrano banali, ma usando lo scripting vengono fuori e rivelano alcune tecniche.

Ad esempio la "rivoluzione" per creare filetti, è una cosa utilissima, ma anche ad esempio uno "sweep" di un profilo per creare i filetti su qualcosa non "rotondo".

Ora provo a spiegare il flusso di lavoro per ottenere il cilindro, lo faccio con lo script:

Code: Select all

"""Sample code.

This code was written as an sample code

Name: filename.py

Author: Carlo Dormeletti
Copyright: 2022
Licence: CC BY-NC-ND 4.0 IT
"""
import os # noqa
import sys  # noqa
import math # noqa
from math import pi, sin, cos # noqa

import FreeCAD
import FreeCADGui # noqa
from FreeCAD import Placement, Rotation, Vector # noqa
import Part # noqa
import DraftGeomUtils

DOC = FreeCAD.activeDocument()

DOC_NAME = "template"


def clear_doc():
    """Clear active document deleting all the objects."""
    for obj in DOC.Objects:
        DOC.removeObject(obj.Name)


def setview():
    """Rearrange View."""
    FreeCAD.Gui.SendMsgToActiveView("ViewFit")
    FreeCAD.Gui.activeDocument().activeView().viewAxometric()
    FreeCAD.Gui.activeDocument().activeView().setAxisCross(True)

if DOC is None:
    FreeCAD.newDocument(DOC_NAME)
    FreeCAD.setActiveDocument(DOC_NAME)
    DOC = FreeCAD.activeDocument()

else:

    clear_doc()

# EPS= tolerance to use to cut the parts
EPS = 0.10
EPS_C = EPS * -0.5
ROT0 = Rotation(0, 0, 0)

def mypol_p(pts, dbg=False):
    """Generate a wire, using a descriptive language.

    Returns:
        wire

    It accepts a list or tuple of coordinates, with some additional
    commands to make complex things.

    (X,Y,Z) Point a line is traced between this and the next pt
    (X,Y,Z, "r", rad) make a fillet of radius (rad) between preceding
                      line and line calculated using this and next pt
    """
    idx = 0
    segs = []
    loop = True

    if dbg is True:
        for idx, pt in enumerate(pts):
            print("idx {}".format(idx))
            print("pt {}".format(pts[idx]))

    idx = 0
    while loop is True:
        if dbg is True:
            print("idx {}".format(idx))

        if len(pts[idx]) == 3:
            pt1 = pts[idx]
            pt2 = pts[idx + 1]
            segs.append(Part.makeLine(pt1, pt2))
            idx += 1
        else:
            if pts[idx][3] == "r":
                rad = pts[idx][4]
                e_a = segs[-1]
                pt2 = Vector(*pts[idx][:3])
                pt3 = Vector(*pts[idx + 1][:3])
                l_b = Part.LineSegment(pt2, pt3).toShape()
                segs.pop()  # delete preceding segment
                fil = DraftGeomUtils.fillet([e_a, l_b], rad, False)
                segs.extend(fil)
                idx += 1

        if idx > (len(pts) - 2):
            # print("loop reached")
            loop = False
        else:
            pass

    if dbg is True:
        print("poly_g = {}".format(segs))

    obj_r = Part.Wire(segs)

    return obj_r


#cilindro

l_cyl = 30
h_cyl = 100
c_rad = 5

pol_p = (
    (0.0, 0.0, 0.0),
    (l_cyl, 0.0, 0.0),
    (l_cyl, h_cyl, 0.0, "r", c_rad),
    (0.0, h_cyl, 0.0),
    (0.0, 0.0, 0.0)
)

mycyl = mypol_p(pol_p)

# Part.show(mycyl, "profilo_cilindro")

faccia = Part.Face(mycyl)
#Part.show(faccia, "faccia_cilindro")

faccia.Placement = Placement(Vector(0, 0, 0), Rotation(0, 0, 90))

cilindro = faccia.revolve(
    Vector(0, 0, 0),  # Centro di rotazione
    Vector(0, 0, 1),  # Asse di rotazione
    360) # Angolo di rotazione

Part.show(cilindro, "cilindro")

DOC.recompute()

setview()

Allora vediamo di spiegare passo passo:

Va creato un "Wire" che riproduce il contorno del cilindro, diventa comodo crearlo in XY dato che usualmente siamo abituati a ragioneare con un paino cartesiano:

Code: Select all

#cilindro

l_cyl = 30
h_cyl = 100
c_rad = 5

pol_p = (
    (0.0, 0.0, 0.0),
    (l_cyl, 0.0, 0.0),
    (l_cyl, h_cyl, 0.0, "r", c_rad),
    (0.0, h_cyl, 0.0),
    (0.0, 0.0, 0.0)
)

mycyl = mypol_p(pol_p)
# Part.show(mycyl, "profilo_cilindro")

Trovi nel codice dei paramteri per regolare il cilindro e il "filetto".

ottieni questo:
20220527-cil_p.png
20220527-cil_p.png (6.04 KiB) Viewed 1349 times
Il profilo va trasformato in una faccia:

Code: Select all

faccia = Part.Face(mycyl)
#Part.show(faccia, "faccia_cilindro")
20220527-cil_f.png
20220527-cil_f.png (5.68 KiB) Viewed 1349 times
e la faccia va ruotata attorno all'asse X:

Code: Select all

faccia.Placement = Placement(Vector(0, 0, 0), Rotation(0, 0, 90))
(nel codice l'ho messa dopo l'istruzione di show per comodità in modo da avere la faccia orientata correttamente per lo screenshot)
20220527-cili_rotx.png
20220527-cili_rotx.png (40.27 KiB) Viewed 1349 times
Nello screenshot si vede il dialogo che appare se clicchi sui tre puntini accanto al "Posizionamento", se lo vuoi fare con la Gui.

Code: Select all

cilindro = faccia.revolve(
    Vector(0, 0, 0),  # Centro di rotazione
    Vector(0, 0, 1),  # Asse di rotazione
    360) # Angolo di rotazione

Part.show(cilindro, "cilindro")
Il codice di rivoluzione è commentato, ovviamente devi ruotare usando come centro l'origine (per quello ho costruito il profilo con la faccia dritta lungo l'asse Y che poi diventa Z una volta ruotata la faccia in posizione).

Questo è il risultato finale:
20220527-cil_rot.png
20220527-cil_rot.png (15.25 KiB) Viewed 1349 times

E questo è il file del codice da caricare in FC per ottenere il solido usando lo scripting.
20220527-cilindro_riv.py
(3.11 KiB) Downloaded 64 times

NOTA:

Per ottenere il "Wire" ho usato una funzione creata da me che fa uso di un paio di trucchi per passare dei parametri a "MakePolygon", si nota l'uso della funzione per creare il filetto tra le due linee, quindi il "filetto funziona", se lo metti in grado di funzionare.

Code: Select all

               fil = DraftGeomUtils.fillet([e_a, l_b], rad, False)
Ho notato che disegnando i contorni "Wire" in "senso antiorario" risulta abbastanza utile, soprattutto perché gli archi di cerchio sono costruiti usando la convenzione "trigonometrica" partendo dall'asse X (se "disegni" in XY) in senso antiorario, diventa tutto più semplice se rispetti il "verso giusto".

Queste cose non sono scritte in modo esplicito da nessuna parte.



Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply