Draft: Better block handling in dxf import & export

This commit is contained in:
Yorik van Havre
2017-04-07 14:08:09 -03:00
parent 3d442e1ea8
commit 1c259fa70b
4 changed files with 70 additions and 22 deletions

View File

@@ -160,11 +160,11 @@ void DraftDxfRead::OnReadText(const double *point, const double /*height*/, cons
void DraftDxfRead::OnReadInsert(const double* point, const double* scale, const char* name, double rotation)
{
//std::cout << "Inserting block " << name << " rotation " << rotation << " pos " << point[0] << "," << point[1] << "," << point[2] << " scale " << scale[0] << "," << scale[1] << "," << scale[2] << std::endl;
std::string prefix = "BLOCKS ";
prefix += name;
prefix += " ";
for(std::map<std::string,std::vector<Part::TopoShape*> > ::const_iterator i = layers.begin(); i != layers.end(); ++i) {
std::string k = i->first;
std::string prefix = "BLOCKS ";
prefix += name;
prefix += " ";
if(k.substr(0, prefix.size()) == prefix) {
BRep_Builder builder;
TopoDS_Compound comp;
@@ -265,6 +265,8 @@ void DraftDxfRead::AddGraphics() const
TopoDS_Compound comp;
builder.MakeCompound(comp);
std::string k = i->first;
if (k == "0") // FreeCAD doesn't like an object name being '0'...
k = "LAYER_0";
std::vector<Part::TopoShape*> v = i->second;
if(k.substr(0, 6) != "BLOCKS") {
for(std::vector<Part::TopoShape*>::const_iterator j = v.begin(); j != v.end(); ++j) {

View File

@@ -1513,6 +1513,40 @@ bool CDxfRead::ReadDimension()
}
bool CDxfRead::ReadBlockInfo()
{
while(!((*m_ifs).eof()))
{
get_line();
int n;
if(sscanf(m_str, "%d", &n) != 1)
{
printf("CDxfRead::ReadBlockInfo() Failed to read integer from '%s'\n", m_str);
return false;
}
std::istringstream ss;
ss.imbue(std::locale("C"));
switch(n){
case 2:
// block name
get_line();
strcpy(m_block_name, m_str);
return true;
case 3:
// block name too???
get_line();
strcpy(m_block_name, m_str);
return true;
default:
// skip the next line
get_line();
break;
}
}
return false;
}
void CDxfRead::get_line()
{
if (m_unused_line[0] != '\0')
@@ -1567,7 +1601,7 @@ bool CDxfRead::ReadUnits()
bool CDxfRead::ReadLayer()
{
std::string layername;
std::string layername;
int aci = -1;
while(!((*m_ifs).eof()))
@@ -1646,23 +1680,15 @@ void CDxfRead::DoRead(const bool ignore_errors /* = false */ )
}
continue;
} // End if - then
else if (!strcmp( m_str, "AcDbBlockBegin" )){
get_line();
if (! strcmp(m_str,"2"))
{
get_line();
strcpy(m_block_name, m_str);
}
} // End if - then
else if(!strcmp(m_str, "0"))
{
get_line();
if (!strcmp( m_str, "SECTION" )){
get_line();
get_line();
strcpy(m_section_name, m_str);
if (strcmp( m_str, "ENTITIES" ))
strcpy(m_section_name, m_str);
strcpy(m_block_name, "");
} // End if - then
@@ -1679,7 +1705,17 @@ void CDxfRead::DoRead(const bool ignore_errors /* = false */ )
printf("CDxfRead::DoRead() Failed to read layer\n");
//return; Some objects or tables can have "LAYER" as name...
}
continue; }
continue;
}
else if (!strcmp( m_str, "BLOCK" )) {
if(!ReadBlockInfo())
{
printf("CDxfRead::DoRead() Failed to read block info\n");
return;
}
continue;
} // End if - then
else if (!strcmp( m_str, "ENDSEC" )){
strcpy(m_section_name, "");
@@ -1805,17 +1841,17 @@ std::string CDxfRead::LayerName() const
if (strlen(m_section_name) > 0)
{
result.append(m_section_name);
result.append(" ");
}
if (strlen(m_block_name) > 0)
{
result.append(" ");
result.append(m_block_name);
result.append(" ");
}
if (strlen(m_layer_name) > 0)
{
result.append(" ");
result.append(m_layer_name);
}

View File

@@ -126,6 +126,7 @@ private:
void OnReadEllipse(const double* c, const double* m, double ratio, double start_angle, double end_angle);
bool ReadInsert();
bool ReadDimension();
bool ReadBlockInfo();
void get_line();
void put_line(const char *value);

View File

@@ -1572,7 +1572,7 @@ def getShapes(filename):
# EXPORT ########################################################################
def projectShape(shape,direction):
def projectShape(shape,direction,tess=None):
import Drawing
edges = []
try:
@@ -1584,7 +1584,12 @@ def projectShape(shape,direction):
for g in groups[0:5]:
if g:
edges.append(g)
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
#return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
if tess:
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges),tess[0],tess[1])
else:
return Part.makeCompound(edges)
#return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
def getArcData(edge):
"returns center, radius, start and end angles of a circle-based edge"
@@ -1905,6 +1910,10 @@ def export(objectslist,filename,nospline=False,lwPoly=False):
elif Draft.getType(ob) == "PanelCut":
writePanelCut(ob,dxf,nospline,lwPoly)
elif ob.isDerivedFrom("Part::Feature"):
tess = None
if hasattr(ob,"Tessellation"):
if ob.Tessellation:
tess = [ob.Tessellation,ob.SegmentLength]
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
sh = None
if not ob.Shape.isNull():
@@ -1912,10 +1921,10 @@ def export(objectslist,filename,nospline=False,lwPoly=False):
elif gui and FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfproject"):
direction = FreeCADGui.ActiveDocument.ActiveView.\
getViewDirection().multiply(-1)
sh = projectShape(ob.Shape,direction)
sh = projectShape(ob.Shape,direction,tess)
else:
if ob.Shape.Volume > 0:
sh = projectShape(ob.Shape,Vector(0,0,1))
sh = projectShape(ob.Shape,Vector(0,0,1),tess)
else:
sh = ob.Shape
if sh: