FMHN#67510 ARC ondersteuning savepoint
svn path=/Slnkdwf/trunk/; revision=52147
This commit is contained in:
@@ -69,6 +69,8 @@ interface IWhipFile : IDispatch{
|
||||
[propget, id(27), helpstring("property vectorDpi")] HRESULT vectorDpi([out, retval] LONG* pVal);
|
||||
[propget, id(28), helpstring("property DwgLimits")] HRESULT DwgLimits([out, retval] IBoundingBox** pVal);
|
||||
[id(29), helpstring("method SymbolOrigin")] HRESULT SymbolOrigin([in] BSTR symbolName, [in] DOUBLE dwgX, [in] DOUBLE dwgY);
|
||||
[propget, id(30), helpstring("property minMergeDistance")] HRESULT minMergeDistance([out, retval] DOUBLE* pVal);
|
||||
[propput, id(30), helpstring("property minMergeDistance")] HRESULT minMergeDistance([in] DOUBLE newVal);
|
||||
};
|
||||
[
|
||||
object,
|
||||
|
||||
@@ -83,9 +83,11 @@ CWhipFile::CWhipFile()
|
||||
m_reLayers.Parse(".*", FALSE);
|
||||
m_hintScale = -1.0;
|
||||
m_minContSize = 0.20e6; // Minimale opp om herkend te worden.
|
||||
m_minMergeDistance = - 1.0; // Minimale mm afstand om lijnsegmenten te mergen, default uit
|
||||
m_forFind = TRUE; // backward compatible
|
||||
m_activeLayerName = "";
|
||||
m_vdpi = 0;
|
||||
m_builder_len = 0;
|
||||
|
||||
// Predefine fixed symbols
|
||||
// Merk op dat m_contunits hier nog gewoon de default identity matrix is
|
||||
@@ -274,6 +276,7 @@ void CWhipFile::read_for_contours()
|
||||
|
||||
m_W2DFile.set_text_action(my_process_text);
|
||||
m_W2DFile.set_polyline_action(my_process_polyline);
|
||||
m_W2DFile.set_outline_ellipse_action(my_process_outlineEllipse);
|
||||
|
||||
// Shiften tijdens *inlezen* om overflow te voorkomen
|
||||
// Problemen: hoe achterhaal je op een nette manier zo vroeg hoeveel je moet shiften
|
||||
@@ -306,6 +309,7 @@ void CWhipFile::read_for_contours()
|
||||
|
||||
// We gaan er later nog een keer door voor de plattegrond. Geen processing dan
|
||||
m_W2DFile.set_text_action(WT_Text::default_process);
|
||||
m_W2DFile.set_outline_ellipse_action(WT_Outline_Ellipse::default_process);
|
||||
m_W2DFile.set_polyline_action(WT_Polyline::default_process);
|
||||
}
|
||||
|
||||
@@ -335,7 +339,7 @@ void CWhipFile::processLabels()
|
||||
for (size_t lbl=0; lbl<m_SLNKLabels.GetCount(); lbl++)
|
||||
{
|
||||
WT_Text text = m_SLNKLabels[lbl];
|
||||
|
||||
bool found = false;
|
||||
// Find inside which Polygon it falls
|
||||
// When multiple: choose smallest!
|
||||
CSLNKContourImpl *prevContour = NULL;
|
||||
@@ -365,6 +369,7 @@ void CWhipFile::processLabels()
|
||||
}
|
||||
else
|
||||
prevContour = contour;
|
||||
found = true;
|
||||
prevContour->m_Key = text.string().ascii();
|
||||
// Spaties voor of achteraan geven op de lange termijn
|
||||
// problemen als we via XML communiceren
|
||||
@@ -399,6 +404,9 @@ void CWhipFile::processLabels()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
myTRACE("\nLabel %s has no matching contour", text.string().ascii());
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -440,6 +448,134 @@ WT_Result CWhipFile::my_process_layer (WT_Layer & layer, WT_File & file)
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
// Kijk of een punt dicht bij het einde van builder ligt
|
||||
bool CWhipFile::pointnearend(CWhipFile *deze, WT_Units units, WT_Logical_Point & pt2)
|
||||
{
|
||||
WT_Logical_Point pt1 = deze->m_builder[deze->m_builder_len - 1];
|
||||
if (pt1 == pt2) // quick shortcut
|
||||
return true;
|
||||
|
||||
WT_Point3D dwgPt1 = units.transform(pt1);
|
||||
WT_Point3D dwgPt2 = units.transform(pt2);
|
||||
|
||||
double dist = sqrt(pow(dwgPt1.m_x - dwgPt2.m_x, 2) + pow(dwgPt1.m_y - dwgPt2.m_y, 2));
|
||||
|
||||
return (dist < deze->m_minMergeDistance); // Minder dan een cm
|
||||
}
|
||||
|
||||
// Kijk of builder nu een gesloten contour vormt.
|
||||
// Zo ja voeg hem dan toe (mits groot genoeg) en reset builder
|
||||
void CWhipFile::test_builder_now_complete(CWhipFile *deze, WT_Units &units)
|
||||
{
|
||||
if (deze->m_builder_len > 3 && pointnearend(deze, units, deze->m_builder[0])) // nu closed? Dan toevoegen!
|
||||
{
|
||||
CSLNKContourImpl *myContour = new CSLNKContourImpl(deze->m_builder_len, deze->m_builder, WD_True, units);
|
||||
myContour->m_DWGArea = PolygonArea(myContour, units);
|
||||
|
||||
WT_Point3D dwgPt = units.transform(myContour->points()[0]);
|
||||
|
||||
myTRACE("\nMerge contour with area %8.0f (%8.2fm2) starting DWF(%3d %d,%d) DWG(%.3f,%.3f)",
|
||||
myContour->m_DWGArea, myContour->m_DWGArea / 1e6,
|
||||
myContour->count(),
|
||||
myContour->points()[0].m_x, myContour->points()[0].m_y,
|
||||
dwgPt.m_x, dwgPt.m_y);
|
||||
|
||||
if (myContour->m_DWGArea >= deze->m_minContSize)
|
||||
deze->m_SLNKContouren.Add(myContour);// Doet uiteindelijk wel een delete op myContour
|
||||
else
|
||||
{
|
||||
myTRACE(" te klein bevonden");
|
||||
delete myContour;
|
||||
}
|
||||
|
||||
deze->m_builder_len = 0; // En resetten
|
||||
}
|
||||
}
|
||||
|
||||
// Punt op arc van sr (start radian) naar er (end radian) met factor tussen 0 en 1
|
||||
WT_Logical_Point radiuspoint(WT_Logical_Point ¢er, double radius, double sr, double er, double factor)
|
||||
{
|
||||
double angle = sr + (er - sr) * factor;
|
||||
return WT_Logical_Point (center.m_x + myRound(radius * cos(angle)),
|
||||
center.m_y + myRound(radius * sin(angle)));
|
||||
}
|
||||
|
||||
void arc2poly(WT_Logical_Point builder[], int &builder_len,
|
||||
WT_Outline_Ellipse & outlineEllipse, bool reverse = false)
|
||||
{
|
||||
double sr = outlineEllipse.start_radian();
|
||||
double er = outlineEllipse.end_radian();
|
||||
if (reverse)
|
||||
{
|
||||
double h = sr;
|
||||
sr = er;
|
||||
er = h;
|
||||
}
|
||||
double radius = outlineEllipse.major();
|
||||
|
||||
int arcsteps = myRound(abs (er - sr) / TWO_PI * 16); // 16 segmenten voor een hele cirkel
|
||||
for (int i = 1; i < arcsteps; i++)
|
||||
builder[builder_len++] = radiuspoint(outlineEllipse.position(), radius, sr, er, ((double) i) / arcsteps);
|
||||
}
|
||||
|
||||
|
||||
WT_Result CWhipFile::my_process_outlineEllipse(WT_Outline_Ellipse & outlineEllipse, WT_File & file)
|
||||
{
|
||||
CWhipFile *deze = (CWhipFile *)file.heuristics().user_data();
|
||||
if (!deze->m_contLayerActive)
|
||||
return WT_Result::Success; // Wrong layer
|
||||
if (deze->m_minMergeDistance < 0)
|
||||
return WT_Result::Success; // We doen niet aan builden
|
||||
|
||||
WT_Units units = fixUnits(file.rendition().viewport().viewport_units());
|
||||
|
||||
WT_Point3D dwgPt = units.transform(outlineEllipse.position());
|
||||
|
||||
myTRACE("\nFound Ellipse center DWF(%d,%d) DWG(%.3f,%.3f) with minor %d major %d startangle %d endangle %d",
|
||||
outlineEllipse.position().m_x, outlineEllipse.position().m_y,
|
||||
dwgPt.m_x, dwgPt.m_y,
|
||||
outlineEllipse.major(), outlineEllipse.minor(),
|
||||
outlineEllipse.start(), outlineEllipse.end());
|
||||
// veronderstel outlineEllipse.major() == outlineEllipse.minor()
|
||||
double sr = outlineEllipse.start_radian();
|
||||
double er = outlineEllipse.end_radian();
|
||||
double radius = outlineEllipse.major();
|
||||
WT_Logical_Point start = radiuspoint(outlineEllipse.position(), radius, sr, er, 0.0);
|
||||
WT_Logical_Point end = radiuspoint(outlineEllipse.position(), radius, sr, er, 1.0);
|
||||
myTRACE("\n start DWF(%d,%d)\n end DWF(%d,%d)",
|
||||
start.m_x, start.m_y, end.m_x, end.m_y);
|
||||
|
||||
if (deze->m_builder_len == 0) // Het is het allereerste segment, bijv. "100976 - C00 - F2-Model-FMH-ARCS.dwf" A-00..BMC
|
||||
{
|
||||
deze->m_builder[deze->m_builder_len++] = start; // TODO: Soms moeten we mogelijk start en end nog omwisselen?
|
||||
arc2poly(deze->m_builder, deze->m_builder_len, outlineEllipse);
|
||||
deze->m_builder[deze->m_builder_len++] = end;
|
||||
}
|
||||
else // Zijn we aan het builden. Kijk of onze ellipse achteraan aansluit
|
||||
{
|
||||
if (pointnearend(deze, units, start))
|
||||
{
|
||||
//deze->m_builder[deze->m_builder_len++] = start;
|
||||
arc2poly(deze->m_builder, deze->m_builder_len, outlineEllipse);
|
||||
deze->m_builder[deze->m_builder_len++] = end;
|
||||
test_builder_now_complete(deze, units);
|
||||
}
|
||||
else if (pointnearend(deze, units, end))
|
||||
{
|
||||
//deze->m_builder[deze->m_builder_len++] = end;
|
||||
arc2poly(deze->m_builder, deze->m_builder_len, outlineEllipse, true /* reverse */);
|
||||
deze->m_builder[deze->m_builder_len++] = start;
|
||||
test_builder_now_complete(deze, units);
|
||||
}
|
||||
else // Sluit niet aan, reset builder
|
||||
{
|
||||
deze->m_builder_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
// This is what AutoCAD seems to create for a normal closed polyline
|
||||
// but also for the rendition of the character '0'
|
||||
WT_Result CWhipFile::my_process_polyline(WT_Polyline & polyline, WT_File & file)
|
||||
@@ -453,7 +589,7 @@ WT_Result CWhipFile::my_process_polyline(WT_Polyline & polyline, WT_File & file)
|
||||
// (Vigor) DWF's uit ARKEY hebben de onhebbelijke eigenschap dat de contour begint
|
||||
// met een aanhaallijntje. Dat ondersteunen we dan toch maar.
|
||||
bool scndIsLast = false;
|
||||
if (g_SLNKOptions.m_SkipContLeader && polyline.count()>1)
|
||||
if (g_SLNKOptions.m_SkipContLeader && polyline.count() > 2) // Pas op dat je de 'L' van 2 punten niet negeert (voor builden)
|
||||
{
|
||||
scndIsLast = (polyline.points()[1].m_x == polyline.points()[polyline.count()-1].m_x &&
|
||||
polyline.points()[1].m_y == polyline.points()[polyline.count()-1].m_y);
|
||||
@@ -461,20 +597,47 @@ WT_Result CWhipFile::my_process_polyline(WT_Polyline & polyline, WT_File & file)
|
||||
// Houthoff tekening 1082ma50-F-B---04-Model.dwf had voor ruimte 04.44 dat
|
||||
// de contour nog <20><>n lijntje doorliep na sluiten. Dat ondersteunen we hier maar.
|
||||
bool xscndIsFirst = false; // een-na-laatste
|
||||
if (polyline.count()>1)
|
||||
if (polyline.count() > 2) // Pas op dat je de 'L' van 2 punten niet negeert (voor builden)
|
||||
{
|
||||
xscndIsFirst = (polyline.points()[0].m_x == polyline.points()[polyline.count()-2].m_x &&
|
||||
polyline.points()[0].m_y == polyline.points()[polyline.count()-2].m_y);
|
||||
}
|
||||
if (!frstIsLast && !scndIsLast && !xscndIsFirst)
|
||||
return WT_Result::Success; // Not closed. Who cares
|
||||
|
||||
xxxx++;
|
||||
|
||||
//WT_Units units=file.rendition().drawing_info().units(); werkt niet goed met paperspace
|
||||
// Waarom zetten we hier m_contunits eigenlijk nog niet gewoon direct?
|
||||
WT_Units units = fixUnits(file.rendition().viewport().viewport_units());
|
||||
|
||||
// if (polyline.count() == 3 && polyline.points()[0].m_x == 2147470970 && polyline.points()[0].m_y == 22603)
|
||||
// DebugBreak();
|
||||
// if (polyline.count() == 2)
|
||||
// DebugBreak();
|
||||
|
||||
|
||||
if (!frstIsLast && !scndIsLast && !xscndIsFirst) // Niet gesloten. Misschien met builder aan de slag?
|
||||
{
|
||||
if (deze->m_minMergeDistance < 0)
|
||||
return WT_Result::Success; // We doen niet aan builden
|
||||
|
||||
if (!pointnearend(deze, units, polyline.points()[0])) //
|
||||
deze->m_builder_len = 0;
|
||||
|
||||
if (deze->m_builder_len == 0 || pointnearend(deze, units, polyline.points()[0]))
|
||||
{
|
||||
for (int i = deze->m_builder_len == 0 ? 0 : 1; i < polyline.count(); i++) // eerste eventueel overslaan, die matchte tenslotte
|
||||
{
|
||||
deze->m_builder[deze->m_builder_len++] = polyline.points()[i];
|
||||
}
|
||||
test_builder_now_complete(deze, units);
|
||||
}
|
||||
else
|
||||
{
|
||||
deze->m_builder_len = 0; // Anders resetten
|
||||
}
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
xxxx++;
|
||||
|
||||
// WD_True as we are going to mess
|
||||
CSLNKContourImpl *myContour;
|
||||
if (scndIsLast) // eerste lijntje droppen
|
||||
@@ -589,8 +752,9 @@ xxxx++;
|
||||
myContour->m_DWGArea = PolygonArea(myContour, units);
|
||||
WT_Point3D dwgPt = units.transform(myContour->points()[0]);
|
||||
|
||||
myTRACE("\nFound contour with area %8.0f (%8.2fm2) starting DWF(%d,%d) DWG(%.3f,%.3f)",
|
||||
myTRACE("\nFound contour with area %8.0f (%8.2fm2) starting DWF(%3d %d,%d) DWG(%.3f,%.3f)",
|
||||
myContour->m_DWGArea, myContour->m_DWGArea/1e6,
|
||||
myContour->count(),
|
||||
myContour->points()[0].m_x, myContour->points()[0].m_y,
|
||||
dwgPt.m_x, dwgPt.m_y);
|
||||
if (myContour->m_DWGArea >= deze->m_minContSize)
|
||||
@@ -601,6 +765,8 @@ xxxx++;
|
||||
delete myContour;
|
||||
}
|
||||
|
||||
deze->m_builder_len = 0; // In ieder geval resetten
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
@@ -730,12 +896,21 @@ HRESULT CWhipFile::SerializePlan(WT_File & my_plan_file, myWT_File & my_file, do
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case WT_Object::Informational:
|
||||
my_plan_file.current_object()->serialize(my_file);
|
||||
break;
|
||||
case WT_Object::Wrapper:
|
||||
// my_plan_file.current_object()->serialize(my_file); // Geeft dubbele (W2D V06.00)
|
||||
break;
|
||||
case WT_Object::Definition:
|
||||
my_plan_file.current_object()->serialize(my_file);
|
||||
break;
|
||||
default:
|
||||
#ifdef _DEBUG
|
||||
CString s(my_plan_file.file_stats()->descriptions());
|
||||
//myTRACE("Skipping '%s'\n", s);
|
||||
CString s(my_plan_file.file_stats()->descriptions());
|
||||
myTRACE("Skipping '%s'\n", s);
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,6 +1566,19 @@ STDMETHODIMP CWhipFile::put_minContSize(DOUBLE newVal)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CWhipFile::get_minMergeDistance(DOUBLE* pVal)
|
||||
{
|
||||
(*pVal) = m_minMergeDistance;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CWhipFile::put_minMergeDistance(DOUBLE newVal)
|
||||
{
|
||||
m_minMergeDistance = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP CWhipFile::get_AddContour(ISLNKContour** pVal)
|
||||
{
|
||||
// Je mag eigenlijk geen echt lege contour doorgeven, daar assert de pointset.cpp op?
|
||||
|
||||
@@ -88,6 +88,10 @@ private:
|
||||
myWT_File m_W2DFile;
|
||||
long m_vdpi;
|
||||
WT_View m_view; // Initial view
|
||||
|
||||
WT_Logical_Point m_builder[1000]; // om lijnstukken aan elkaar te plakken
|
||||
int m_builder_len;
|
||||
|
||||
HRESULT ProcessContouren();
|
||||
HRESULT SerializePlan(WT_File & my_plan_file, myWT_File & my_file, double scale);
|
||||
|
||||
@@ -101,10 +105,13 @@ private:
|
||||
STDMETHOD(Generate)(myWT_File &my_file);
|
||||
void read_for_contours();
|
||||
void processLabels();
|
||||
static WT_Result my_process_layer (WT_Layer & layer, WT_File & file);
|
||||
static bool pointnearend(CWhipFile *deze, WT_Units units, WT_Logical_Point & pt2);
|
||||
static void test_builder_now_complete(CWhipFile *deze, WT_Units &units);
|
||||
static WT_Result my_process_layer(WT_Layer & layer, WT_File & file);
|
||||
//static WT_Result my_process_polygon(WT_Polygon & polygon, WT_File & file);
|
||||
static WT_Result my_process_outlineEllipse(WT_Outline_Ellipse & outlineEllipse, WT_File & file);
|
||||
static WT_Result my_process_polyline(WT_Polyline & polyline, WT_File & file);
|
||||
static WT_Result my_process_polytriangle(WT_Polytriangle & polytriangle, WT_File & file);
|
||||
//static WT_Result my_process_polytriangle(WT_Polytriangle & polytriangle, WT_File & file);
|
||||
static WT_Result my_process_text (WT_Text & text, WT_File & file);
|
||||
public:
|
||||
STDMETHOD(get_hintScale)(DOUBLE* pVal);
|
||||
@@ -115,6 +122,8 @@ public:
|
||||
STDMETHOD(return_ContourItem)(CSLNKContourImpl *pContour, ISLNKContour** pVal);
|
||||
STDMETHOD(get_minContSize)(DOUBLE* pVal);
|
||||
STDMETHOD(put_minContSize)(DOUBLE newVal);
|
||||
STDMETHOD(get_minMergeDistance)(DOUBLE* pVal);
|
||||
STDMETHOD(put_minMergeDistance)(DOUBLE newVal);
|
||||
STDMETHOD(get_vectorDpi)(LONG* pVal);
|
||||
STDMETHOD(get_DwgLimits)(IBoundingBox** pVal);
|
||||
|
||||
@@ -168,6 +177,8 @@ public:
|
||||
BOOL m_labelLayerActive;
|
||||
double m_hintScale; // Kunnen we gebruiken om symbolen te 'geeken'
|
||||
double m_minContSize; // Minimale oppervlakte om als contour te erkend worden
|
||||
double m_minMergeDistance; // Minimale afstand om lijnsegmenten te mergen
|
||||
|
||||
BOOL m_forFind; // Extra info die we kunnen misbruiken
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user