Данный код был написан моим сотрудником. Мне этот код не нравится, но он мне отвечает что я субъективен и его код неплох.
// SewingDlg.h
#pragma once
#include "MainHeaders.h"
#include "afxwin.h"
#include <vector>
#include <map>
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
class KompasObjectHolder
{
protected:
reference m_reference;
public:
KompasObjectHolder() : m_reference(0) {}
KompasObjectHolder(reference object_reference) : m_reference(object_reference) {}
KompasObjectHolder(KompasObjectHolder& prev_holder) : m_reference(prev_holder.m_reference) { prev_holder.m_reference = 0; }
KompasObjectHolder& operator =(KompasObjectHolder& prev_holder) {
if (!m_reference) m_reference = prev_holder.m_reference, prev_holder.m_reference = 0; return *this; }
~KompasObjectHolder()
{
if (m_reference) DeleteObj(m_reference);
m_reference = 0;
}
operator reference() { return m_reference; }
operator bool() { return m_reference != 0; }
};
class KompasIteratorHolder : public KompasObjectHolder
{
public:
KompasIteratorHolder() {}
KompasIteratorHolder(reference iterator_reference) : KompasObjectHolder(iterator_reference) {}
KompasIteratorHolder& operator =(KompasIteratorHolder& prev_holder) {
if (!m_reference) m_reference = prev_holder.m_reference, prev_holder.m_reference = 0; return *this; }
~KompasIteratorHolder()
{
if (m_reference) DeleteIterator(m_reference);
m_reference = 0;
}
};
class CSewingDlg : public CDialog // диалоговое окно CSewingDlg
{
DECLARE_DYNAMIC(CSewingDlg)
public:
CSewingDlg(CWnd* pParent = NULL); // стандартный конструктор
virtual ~CSewingDlg();
reference Draw2DElement(reference element, bool closed = false);
reference DrawLineSeg(reference element);
reference DrawCircle(reference element);
reference DrawArc(reference element);
reference DrawEllipse(reference element);
reference DrawEllipseArc(reference element); // BAD when coercing EllipseArc & Nurbs ??bag in KOMPAS
reference DrawEllipseArcWithNurbs(reference element); // new API7+IMath2D version - !EllipseArc as case of Nurbs
reference DrawRectangle(reference element);
reference DrawRegularPolygon(reference element);
reference DrawBezier(reference element, bool closed = false); // new API7 version - allows Bezier 2 type (Equidistants fail too)
reference DrawBezierWithNurbs(reference element, bool closed); // new API7+IMath2D version - !Bezier as case of Nurbs
reference DrawEquidistant7(IDrawingObjectPtr& idcContour,
EquidistantParam *equiparam, bool swapped); // new API7 version - no adv.features
reference DrawEquidistant(EquidistantParam *equiparam, bool swapped); // new API5 version - ?
reference DrawPolyline(reference element, bool closed = false);
reference DrawApproximation(reference element, int curve_type);
reference DrawContour(reference element, bool closed = false);
reference DrawNurbs(reference element, bool closed = false); // new API7+IMath2D version - !works
reference SmallNurbs3(double x1, double y1, double x2, double y2, unsigned short style);
double CurvesDeviation(reference old_curve, ICurve2DPtr& new_curve, double precision, double* tpars, int points_count);
inline void KompasCorrectAngles(double& dBeginAngle, double& dEndAngle, bool clockwise);
int PseudoProcessAcceptedData(void* pInputData, EquidistantParam *equiparam, bool PseudoGroupMode);
void PrepareContoursMakeEquidistants(reference obj_iterator, EquidistantParam* equiparam);
void ProcessMarks(reference curve, reference contour, EquidistantParam* equiparam);
bool CheckSwapBegPoint(double& x1, double& y1, double& x2, double& y2);
bool CheckTipWithScratch(double& x1, double& y1);
bool CheckSwapCurve(reference curve);
reference DestroyContoursGroup(int tipSearch);
double GetEquidistantPerimeter(reference element); // using destroyObj to get true length of Equidistant
int CheckContourSide(reference contour, bool swapped, bool issingle);
int CheckIntersections(reference contour, bool swapped, double t);
bool TestInterrupt(LPSTR msg, int count);
void api7test();
bool Activated;
PointParam m_BegPoint;
reference m_grpAuxScratches;
unsigned short m_curves_style;
// Данные диалогового окна
enum { IDD = IDD_SEWINGDLG };
enum { enCurves_All = 0, enCurves_Selected, enCurves_Unselected };
protected:
virtual BOOL OnInitDialog();
void ParseDoubleData(int nID);
virtual void DoDataExchange(CDataExchange* pDX); // поддержка DDX/DDV
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedDrawOperation();
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedUndo();
afx_msg void OnBnClickedRedo();
protected:
int m_StockOutCheck;
int m_StockInCheck;
int m_MarkingCheck;
double m_StockOut;
double m_StockIn;
double m_MarkingStep;
int m_SelectType;
private:
int m_UndoRedo;
int m_ProcessClosedOnly;
int m_ContourHasAnyLineStyles;
int m_ProcessEnclosedContours;
int m_MaxSplitNum;
int m_MaxMarksNum;
double m_MmToUnits;
double m_precision;
std::map<reference, reference> m_CurveParts;
std::vector<reference> equi_curves; // tmp vector needed to correct Equidistant behavior
int equi_curves_count; // may differ from equi_curves.size() due to m_grpAuxScratches
bool m_swapped;
bool m_issingle;
reference m_aux_scratch;
bool m_skip_scratch; // in API5 Contour()-mode all references are 0 = i.e. temp intrinsic objects for Contour()
public:
afx_msg void OnBnClickedManualMarks();
afx_msg void OnEnKillfocusPrecision();
afx_msg void OnEnKillfocusStockout();
afx_msg void OnEnKillfocusStockin();
afx_msg void OnEnKillfocusMarking();
afx_msg void OnEnChangeMarking();
};
// SewingDlg.cpp: файл реализации
//
#include "stdafx.h"
#include "SewingDlg.h"
#include "ProgressDlg.h"
#include "SewingPlugin.h"
#include "testEvents/BaseEvent.h"
#include <limits>
#include <cmath>
#include <algorithm>
const double PI2DEGREE = 180.0 / 3.14159265;
const int EQUI_STYLE = ksCSConstruction; // 6 : вспомогательная (красная)
extern BOOL glb_Interrupt;
// from eventsAuto.cpp
void AdviseDoc( KompasObject* kompas,
LPDISPATCH doc, long docType,
bool fSelectMng = true,
bool fObject = true,
bool fStamp = true,
bool fDocument = true,
bool fSpecification = true,
bool fSpcObject = true,
long objType = 0 /*= -1*/);
#if defined(ASSERT) && !defined(_DEBUG)
#undef ASSERT
#define FILEW2(x) L##x
#define FILEW(f) FILEW2(f)
#define ASSERT(f) {CString sss;if (!(f)){sss.Format(L"BAD ASSERT in line %d (file " FILEW(__FILE__) L")", __LINE__);MessageW((LPWSTR)sss.GetString());}}
#endif
#define MESSAGE_COMMA ,
#define MESSAGE(mesh) { CString sss; sss.Format(mesh); MessageW((LPWSTR)sss.GetString()); }
template<typename FloatType> inline // to improve need call_traits, etc
bool approx_equals(FloatType x, FloatType y, FloatType relative_factor=FloatType(64))
{
// default relative_factor=64 results in approximately 2 decimal digits tolerance in significand
using std::abs; using std::max; using std::numeric_limits;
return abs(x-y) <= ( relative_factor * numeric_limits<FloatType>::epsilon() * max(abs(x),abs(y)) );
}
static inline bool equal_points(double x1, double y1, double x2, double y2, double precision = 0.0)
{
// double epsilon = 1e-16, so 1e9 gives real Kompas precision about 1e-7..1e-6..1e-5
//return VTSL::Math::approx_equals<double>( x1, x2, double(1e9) ) && VTSL::Math::approx_equals<double>( y1, y2, double(1e9) );
using std::abs; using std::max; using std::numeric_limits;
double minerror = DBL_EPSILON * double(1e9);
if (precision > minerror)
return max(abs(x1 - x2), abs(y1 - y2)) <= precision;
//Message("equal_points");
// double correction = double(1e9) * (precision <= minerror? 1.0 : precision / minerror);
double correction = (precision <= minerror? minerror : precision) / DBL_EPSILON;
bool bx, by;
double absmax = max(abs(x1), abs(x2));
if ( absmax > 1.0 ) bx = approx_equals<double>( x1, x2, correction );
else {
if ( absmax < minerror ) bx = true;
else bx = approx_equals<double>( x1/absmax, x2/absmax, correction );
}
absmax = max(abs(y1), abs(y2));
if ( absmax > 1.0 ) by = approx_equals<double>( y1, y2, correction );
else {
if ( absmax < minerror ) by = true;
else by = approx_equals<double>( y1/absmax, y2/absmax, correction );
}
return bx && by;
}
static inline bool equal_values(double val1, double val2, double precision = 0.0)
{
const double minerror = DBL_EPSILON * double(1e9);
// double correction = double(1e9) * (precision <= minerror? 1.0 : precision / minerror);
double correction = (precision <= minerror? minerror : precision) / DBL_EPSILON;
double absmax = std::max(abs(val1), abs(val2));
if ( absmax < 1.0 )
{
if (absmax < minerror) return true; // DBL_EPSILON * 64
return approx_equals<double>( val1/absmax, val2/absmax, correction);
}
return approx_equals<double>( val1, val2, correction);
}
static bool IsContourInsideContour(reference contour, reference other, CSewingDlg* pThis)
{
int type = GetObjParam(other, 0, 0, ALLPARAM);
int side = 0;
double t1, t2, x1, y1, x2, y2;
ksGetCurveMinMaxParametr (contour, &t1, &t2);
ksGetCurvePoint(contour, t1, &x1, &y1);
ksGetCurvePoint(contour, t2, &x2, &y2);
if (type == CONTOUR_OBJ) {
side = ksIsPointInsideContour(other, x1, y1, 1e-6);
}
if (side == 0) { // special cases for single bezier contour etc.
reference bref = ksApproximationCurve(other, 0.1, 0, 0, 1);
if (bref)
{
int type = GetObjParam(bref, 0, 0, ALLPARAM);
if (type == CONTOUR_OBJ) {
side = ksIsPointInsideContour(bref, x1, y1, 1e-6);
}
DeleteObj(bref);
}
}
if (side == 0) do { // special cases for single rectangle, circle etc.
KompasObjectHolder decomposed_group(DecomposeObj(other, 5, 0.5, 1));
if (!decomposed_group) break;
KompasIteratorHolder group_iterator(CreateIterator(ALL_OBJ, decomposed_group));
if (!group_iterator) break;
Contour(1);
reference cur_obj = MoveIterator(group_iterator, 'F');
while (cur_obj)
{
pThis->Draw2DElement(cur_obj);
cur_obj = MoveIterator(group_iterator, 'N');
}
reference contour_obj = EndObj();
if (contour_obj)
side = ksIsPointInsideContour(contour_obj, x1, y1, 1e-6);
if (contour_obj) DeleteObj(contour_obj);
} while (0);
if (side == 3) {
Message("IsContourInsideContour");
int kp = 0;
IntersectCurvCurv (contour, other, &kp, 0, 0, 0);
if (kp == 0) return true;
}
return false;
}
// диалоговое окно CSewingDlg
IMPLEMENT_DYNAMIC(CSewingDlg, CDialog)
CSewingDlg::CSewingDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSewingDlg::IDD, pParent)
, m_StockInCheck(false)
, m_StockOutCheck(false)
, m_MarkingCheck(false)
, m_StockOut(0)
, m_StockIn(0)
, m_MarkingStep(0)
, m_SelectType(0)
, m_UndoRedo(0)
, m_ProcessClosedOnly(1)
, m_ContourHasAnyLineStyles(0)
, m_ProcessEnclosedContours(0) // enclosing may be too slow
, m_MaxSplitNum(20)
, m_MaxMarksNum(10)
, m_precision(1.0)
{
Activated = true;
m_BegPoint.x = m_BegPoint.y = 0;
m_BegPoint.style = 0;
m_grpAuxScratches = 0; m_curves_style = 0;
m_MmToUnits = 1.0;
m_swapped = m_issingle = false;
m_aux_scratch = 0; m_skip_scratch = false;
}
CSewingDlg::~CSewingDlg()
{
}
void CSewingDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Radio(pDX, IDC_RADIO1, m_SelectType);
DDX_Check(pDX, IDC_STOCKOUT_CHECK, m_StockOutCheck);
DDX_Check(pDX, IDC_STOCKIN_CHECK, m_StockInCheck);
DDX_Check(pDX, IDC_MARKING_CHECK, m_MarkingCheck);
DDX_Check(pDX, IDC_PROCESS_CLOSED_ONLY, m_ProcessClosedOnly);
DDX_Check(pDX, IDC_CONTOUR_HAS_ANY_LINE_STYLES, m_ContourHasAnyLineStyles);
DDX_Check(pDX, IDC_PROCESS_ENCLOSED_CONTUORS, m_ProcessEnclosedContours);
DDX_Text (pDX, IDC_STOCKOUT, m_StockOut);
DDX_Text (pDX, IDC_STOCKIN, m_StockIn);
DDX_Text (pDX, IDC_MARKING, m_MarkingStep);
DDX_Text (pDX, IDC_CURVE_MAX_POINTS, m_MaxSplitNum);
DDX_Text (pDX, IDC_MARKS_PER_CURVE, m_MaxMarksNum);
DDX_Text (pDX, IDC_PRECISION, m_precision);
}
BEGIN_MESSAGE_MAP(CSewingDlg, CDialog)
ON_BN_CLICKED(IDC_DRAW_OPERATION, &CSewingDlg::OnBnClickedDrawOperation)
// ON_WM_ACTIVATE()
ON_WM_KEYDOWN()
ON_BN_CLICKED(IDCANCEL, &CSewingDlg::OnBnClickedCancel)
ON_BN_CLICKED(IDC_UNDO, &CSewingDlg::OnBnClickedUndo)
ON_BN_CLICKED(IDC_REDO, &CSewingDlg::OnBnClickedRedo)
// ON_WM_CHAR()
ON_WM_ACTIVATE()
ON_BN_CLICKED(IDC_MANUAL_MARKS, &CSewingDlg::OnBnClickedManualMarks)
ON_EN_KILLFOCUS(IDC_PRECISION, &CSewingDlg::OnEnKillfocusPrecision)
ON_EN_KILLFOCUS(IDC_STOCKOUT, &CSewingDlg::OnEnKillfocusStockout)
ON_EN_KILLFOCUS(IDC_STOCKIN, &CSewingDlg::OnEnKillfocusStockin)
ON_EN_KILLFOCUS(IDC_MARKING, &CSewingDlg::OnEnKillfocusMarking)
ON_EN_CHANGE(IDC_MARKING, &CSewingDlg::OnEnChangeMarking)
END_MESSAGE_MAP()
//-----------------------------------------------------------------------------
// Dialog initialization
BOOL CSewingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_StockOutCheck = true;
m_StockInCheck = false;
m_MarkingCheck = true;
m_StockOut = 10.50;
m_StockIn = 10.50;
m_MarkingStep = 100;
m_SelectType = 0;
m_MaxSplitNum = 20;
m_MaxMarksNum = 5;
((CButton*)GetDlgItem( IDC_PROCESS_CLOSED_ONLY ))->SetCheck( m_ProcessClosedOnly? 1 : 0 );
((CButton*)GetDlgItem( IDC_CONTOUR_HAS_ANY_LINE_STYLES ))->SetCheck( m_ContourHasAnyLineStyles? 1 : 0 );
((CButton*)GetDlgItem( IDC_PROCESS_ENCLOSED_CONTUORS ))->SetCheck( m_ProcessEnclosedContours? 1 : 0 );
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
/*
//reference obj = Circle(100,100,100,1);
/ *
RectangleParam par; // структура параметров прямоугольника
::memset(&par, 0, sizeof(RectangleParam));
par.x = -73.55; // базовая точка 1
par.y = 39.95; //
par.ang = 0.00; // угол вектора направления от 1-ой точки ко 2-ой
par.height = -66.68; // высота
par.width = 79.90; // ширина
par.pCorner = ::CreateArray(CORNER_ARR, 0); // Создание массива параметров углов
par.style = 1; // стиль линии
reference obj = ::ksRectangle(&par, 0); // создать прямоугольник
* /
/ *
reference rseg1 = LineSeg(10,10,100,100,1);
reference rseg2 = LineSeg(100,100,200,20,1);
reference obj = NewGroup(0);
AddObjGroup(obj, rseg1);
AddObjGroup(obj, rseg2);
EndGroup();* /
Contour(1);
//определим группу выделения
// reference obj0 = SelectGroup(0,2,0,0,0,0); //ksViewGetObjectArea();
//CopyObj(obj0, 0,0,0,0,1,1);
//CopyGroupToDocument(obj0, ksGetCurrentDocument(0), ksGetCurrentDocument(0));
// reference group_iterator = CreateIterator(LINESEG_OBJ, 0);
reference group_iterator = CreateIterator(SELECT_GROUP_OBJ, 0);
reference cur_obj = MoveIterator(group_iterator, 'F');
while (cur_obj)
{
ksLineSegParamPtr lspLineParam = kompasAPI->GetParamStruct(ko_LineSegParam);
// long ksres = sewing_object->m_pKompasDoc5->ksGetObjParam(cur_obj, lspLineParam, ALLPARAM);
long ksres = m_pKompasDoc5->ksGetObjParam(cur_obj, lspLineParam, ALLPARAM);
if(ksres)
{
double x1 = lspLineParam->x1,
x2 = lspLineParam->x2,
y1 = lspLineParam->y1,
y2 = lspLineParam->y2;
// LineSeg(x1,y1,x2,y2,1);
/ * задание параметров копирования * /
/ *
RequestInfo info;
memset(&info, 0, sizeof(info));
info.title = "Title";
info.prompt = " Новое положение базовой точки ";
info.dynamic = 0;
info.commands = "!test!test1";
int j=CommandWindow(&info);
double x=0,y=0,scale=1,ang=0;
if ((Cursor (&info, &x, &y, 0)) &&
(ReadDouble("Угол поворота", 0, 0, 360, &ang)) &&
(ReadDouble("Масштаб", 1, 0, 999, &scale)))
;* /
/ *
reference posLeader = ksCreateViewObject(POSLEADER_OBJ );
if (posLeader){
LightObj(posLeader, 1);
Message("Позиционная линия выноски");
LightObj(posLeader, 0);
if (ksEditViewObject(posLeader)) {
LightObj(posLeader, 1);
Message("Отредактированная позиционная линия выноски");
LightObj(posLeader, 0);
}
}
* /
//CopyObj(0, 0, 0, x, y, ang, scale); / * копирование группы gr * /
//ksCopyObj(0, 0, 0, x, y, ang, scale); / * копирование группы gr * /
LineSeg(x1,y1,x2,y2,1);
*/
reference CSewingDlg::Draw2DElement(reference element, bool closed)
{
if (ReturnResult()) ResultNULL();
if (!ExistObj(element)) return 0;
switch (GetObjParam(element, 0, 0, ALLPARAM))
{
case CONTOUR_OBJ:
return DrawContour(element); // ONLY APPROXIMATION NOW
case LINESEG_OBJ:
return DrawLineSeg(element);
case CIRCLE_OBJ:
return DrawCircle(element);
case ELLIPSE_OBJ:
return DrawEllipse(element);
case ARC_OBJ:
return DrawArc(element);
case ELLIPSE_ARC_OBJ:
//return DrawEllipseArcWithNurbs(element);
return DrawEllipseArc(element); // NO APPROXIMATION possible - it approximates into itself!
case RECTANGLE_OBJ:
return DrawRectangle(element);
case REGULARPOLYGON_OBJ:
return DrawRegularPolygon(element);
case BEZIER_OBJ:
return DrawBezierWithNurbs(element, closed);
//return DrawBezier(element, closed);
case POLYLINE_OBJ:
return DrawPolyline(element, closed);
case NURBS_OBJ:
return DrawNurbs(element, closed);
default:
break;
}
return 0;
}
reference CSewingDlg::SmallNurbs3(double x1, double y1, double x2, double y2, unsigned short style)
{
//Message("SmallNurbs3");
reference new_curve = 0;
do {
const int degree = 3 + 0; // NURBS-3 needs 3 points
bool closed = false;
NurbsPointParam par;
Nurbs(degree, closed, style);
std::vector<double> Points;
//std::vector<double> Weights;
//std::vector<double> Knots;
Points.push_back(x1), Points.push_back(y1);
Points.push_back((x1 + x2) / 2), Points.push_back((y1 + y2) / 2);
Points.push_back(x2), Points.push_back(y2);
int basepoint_count = Points.size();
for (int basepoint = 0; basepoint < basepoint_count; basepoint += 2)
{
par.x = Points[basepoint];
par.y = Points[basepoint + 1];
par.weight = 1.0;
NurbsPoint(&par);
}
int knot_count = basepoint_count / 2 + degree;
for (int knot = 0; knot < knot_count; knot++)
{
double knotdata = double(knot / degree); // ONLY for 3 Points on 3 degree
ksNurbsKnot(knotdata);
}
new_curve = EndObj();
if (new_curve) return new_curve; // => new_curve may be 0! like for Bezier !?
} while (0);
return 0;
}
bool CSewingDlg::CheckTipWithScratch(double& x1, double& y1)
{
if (equal_points(x1,y1, m_BegPoint.x, m_BegPoint.y, m_precision * m_MmToUnits)) {
//if (equal_points(x1,y1, m_BegPoint.x, m_BegPoint.y) == false) {
if (m_skip_scratch == false)
if ( ksEqualPoints(x1, y1, m_BegPoint.x, m_BegPoint.y) == 0 ) {
reference aux_scratch = LineSeg(m_BegPoint.x, m_BegPoint.y, x1, y1, m_curves_style);
if (aux_scratch == 0) aux_scratch = SmallNurbs3(m_BegPoint.x, m_BegPoint.y, x1, y1, m_curves_style);
if (aux_scratch) AddObjGroup(m_grpAuxScratches, aux_scratch);
if (aux_scratch == 0)
Message("CheckSwapBegPoint - BAD scratch!");
//else Message("Tip drawn");
m_aux_scratch = aux_scratch;
}
return true;
}
return false;
}
bool CSewingDlg::CheckSwapBegPoint(double& x1, double& y1, double& x2, double& y2)
{
if (CheckTipWithScratch(x1, y1)) {
m_BegPoint.x = x2, m_BegPoint.y = y2;
return false;
}
if (CheckTipWithScratch(x2, y2)) {
//Message("CheckSwapBegPoint - SWAPPED!");
m_BegPoint.x = x1, m_BegPoint.y = y1;
x1 = x2, y1 = y2;
x2 = m_BegPoint.x, y2 = m_BegPoint.y;
return true;
}
return false;
}
bool CSewingDlg::CheckSwapCurve(reference curve)
{
double t1, t2;
double x1, y1, x2, y2;
ksGetCurveMinMaxParametr (curve, &t1, &t2);
ksGetCurvePoint(curve, t1, &x1, &y1);
ksGetCurvePoint(curve, t2, &x2, &y2);
//return (equal_points(x1,y1, m_BegPoint.x, m_BegPoint.y, m_precision * m_MmToUnits) == false);
return ( ksEqualPoints(x1, y1, m_BegPoint.x, m_BegPoint.y) == 0 );
}
bool CSewingDlg::TestInterrupt(LPSTR msg, int count)
{
if (glb_Interrupt && YesNo(msg) == 1) return true;
//Message("TestInterrupt");
// HWND hwnd = ::SetActiveWindow((HWND) GetHWindow());
// PumpWaitingMessages();
ksSetProgressBar(count, "Отрисовка эквидистант...", 1);
if (progress_object) {
((CProgressCtrl*)progress_object->GetDlgItem( IDC_PROGRESS ))->SetPos(count);
if (((CProgressCtrl*)progress_object->GetDlgItem( IDCANCEL ))->IsWindowEnabled() == FALSE) {
((CProgressCtrl*)progress_object->GetDlgItem( IDCANCEL ))->EnableWindow(TRUE);
((CProgressCtrl*)progress_object->GetDlgItem( IDCANCEL ))->SetWindowTextW(L"Отмена");
}
}
glb_Interrupt = FALSE;
// ::SetActiveWindow(hwnd);
PumpWaitingMessages();
return false;
}
void CSewingDlg::KompasCorrectAngles(double& dBeginAngle, double& dEndAngle, bool clockwise)
{
// KOMPAS angles sometimes need correction!:
if (clockwise) {
if (dBeginAngle - dEndAngle > 360) dBeginAngle -= 360 * floor((dBeginAngle - dEndAngle) / 360.0);
} else {
if (dEndAngle - dBeginAngle > 360) dEndAngle -= 360 * floor((dEndAngle - dBeginAngle) / 360.0);
}
if (dBeginAngle < 0.0 || dEndAngle < 0.0) {
dBeginAngle = dBeginAngle - 360 * floor(dBeginAngle / 360.0);
dEndAngle = dEndAngle - 360 * floor(dEndAngle / 360.0);
}
// Kompas works with angles from 0 to 360 degrees, so may be arcs par ex. from 315 to 45 degrees. DrawArc needs starting angle be less than the ending
if (clockwise) {
if (dEndAngle > dBeginAngle) if (dEndAngle < 360) dBeginAngle += 360; else dEndAngle -= 360;
} else {
if (dEndAngle < dBeginAngle) if (dBeginAngle < 360) dEndAngle += 360; else dBeginAngle -= 360;
}
}
reference CSewingDlg::DrawLineSeg(reference element)
{
//?if ( m_PseudoObjectsMode ) return DrawObjectsAsPseudoVector(element);
ksLineSegParamPtr lspLineParam = kompasAPI->GetParamStruct(ko_LineSegParam);
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D();
long ksres = m_pKompasDoc5->ksGetObjParam(element, lspLineParam, ALLPARAM);
if(ksres)
{
double x1 = lspLineParam->x1,
x2 = lspLineParam->x2,
y1 = lspLineParam->y1,
y2 = lspLineParam->y2;
CheckSwapBegPoint(x1, y1, x2, y2);
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
return LineSeg(x1, y1, x2, y2, 1);
}
return 0;
}
reference CSewingDlg::DrawCircle(reference element)
{
CircleParam cpCircleParam;
if (GetObjParam(element, &cpCircleParam, sizeof(CircleParam), ALLPARAM))
{
double x = cpCircleParam.xc,
y = cpCircleParam.yc;
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
return Circle(x, y, cpCircleParam.rad, 1);
}
return 0;
}
reference CSewingDlg::DrawArc(reference element)
{
//Message("DrawArc");
ArcParam apArcParam;
ArcParam1 apArcParam1;
if (GetObjParam(element, &apArcParam, sizeof(ArcParam), ALLPARAM)
&& GetObjParam(element, &apArcParam1, sizeof(ArcParam1), POINT_ARC_PARAM))
{
double x = apArcParam.xc,
y = apArcParam.yc;
double dBeginAngle = apArcParam.ang1, // as if Arc is drawed counterclockwise
dEndAngle = apArcParam.ang2;
double x1 = apArcParam1.x1, y1 = apArcParam1.y1;
double x2 = apArcParam1.x2, y2 = apArcParam1.y2;
bool clockwise = (apArcParam.dir != 1);
if ( CheckSwapBegPoint(x1, y1, x2, y2) ) {
clockwise = !clockwise;
double tmpang = dBeginAngle;
dBeginAngle = dEndAngle; dEndAngle = tmpang;
}
//KompasCorrectAngles(dBeginAngle, dEndAngle, clockwise); ?? this correction not liked by Equidistant!
double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
return ArcByAngle(x, y, apArcParam.rad, dBeginAngle, dEndAngle, clockwise? -1 : 1, 1);
}
return 0;
}
reference CSewingDlg::DrawEllipse(reference element)
{
EllipseParam epEllipseParam;
if (GetObjParam(element, &epEllipseParam, sizeof(EllipseParam), ALLPARAM))
{
double x = epEllipseParam.xc,
y = epEllipseParam.yc;
double angle = epEllipseParam.ang;
double a = epEllipseParam.a;
double b = epEllipseParam.b;
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
epEllipseParam.style = 1;
return ksEllipse(&epEllipseParam);
}
return 0;
}
reference CSewingDlg::DrawEllipseArcWithNurbs(reference element)
{
Message("DrawEllipseArcWithNurbs");
return 0;
}
reference CSewingDlg::DrawEllipseArc(reference element) // old - BAD in test with Equidistant
{
// return 0; // IMPOSSIBLE to make approximation! (NO WAY TOO to coerce EllipsArc & Nurbes in Equidistant)
//Message("DrawEllipseArc");
EllipseArcParam eapEllipseArcParam;
EllipseArcParam1 eapEllipseArcParam1;
if (GetObjParam(element, &eapEllipseArcParam, sizeof(EllipseArcParam), ALLPARAM) &&
GetObjParam(element, &eapEllipseArcParam1, sizeof(EllipseArcParam), POINT_ARC_PARAM))
{
double x = eapEllipseArcParam.xc,
y = eapEllipseArcParam.yc;
double angle = eapEllipseArcParam.ang;
double ang1 = eapEllipseArcParam.angFirst;
double ang2 = eapEllipseArcParam.angSecond;
double a = eapEllipseArcParam.a;
double b = eapEllipseArcParam.b;
int dir = eapEllipseArcParam.dir;
eapEllipseArcParam.style = eapEllipseArcParam1.style = 1;
ASSERT(eapEllipseArcParam1.a == a && eapEllipseArcParam1.b == b)
ASSERT(eapEllipseArcParam1.ang == angle)
ASSERT(eapEllipseArcParam1.xc == x && eapEllipseArcParam1.yc == y)
ASSERT(eapEllipseArcParam1.dir == dir)
double t1, t2, t2eps;
double x1, y1, x2, y2, x1eps, y1eps, x2eps, y2eps;
ksGetCurveMinMaxParametr (element, &t1, &t2);
if (dir == 1)
ASSERT(t2 - t1 == eapEllipseArcParam1.parSecond - eapEllipseArcParam1.parFirst)
else
ASSERT(t1 - t2 == eapEllipseArcParam1.parSecond - eapEllipseArcParam1.parFirst)
//ASSERT(t1 == eapEllipseArcParam.parFirst && t2 == eapEllipseArcParam.parSecond)
//! t1 != eapEllipseArcParam.parFirst even though (t2 - t1) == (eapEllipseArcParam.parSecond - eapEllipseArcParam.parFirst)!
//t1 = eapEllipseArcParam.parFirst; // or just: ksGetCurveMinMaxParametr (element, &t1, &t2);
//t2 = eapEllipseArcParam.parSecond;
ksGetCurvePoint(element, t1, &x1, &y1); //? BAD instead of t1: (dir == 1? t1 : t2)! (by the way, for contours HERE dir==1 means CLOCKWISE!?)
ksGetCurvePoint(element, t2, &x2, &y2);
double tstep = (t2 - t1) * 0.01 * 0;
ksGetCurvePoint(element, t1 + tstep, &x1eps, &y1eps);
ksGetCurvePoint(element, t2 - tstep, &x2eps, &y2eps);
eapEllipseArcParam1.parFirst = eapEllipseArcParam1.parFirst + tstep;
eapEllipseArcParam1.parSecond = eapEllipseArcParam1.parSecond - tstep;
if ( CheckSwapBegPoint(x1, y1, x2, y2) ) {
eapEllipseArcParam.dir = - eapEllipseArcParam.dir;
double tmpang = eapEllipseArcParam.angFirst;
eapEllipseArcParam.angFirst = eapEllipseArcParam.angSecond;
eapEllipseArcParam.angSecond = tmpang;
eapEllipseArcParam1.dir = eapEllipseArcParam.dir;
double tmppar = eapEllipseArcParam1.parFirst;
eapEllipseArcParam1.parFirst = eapEllipseArcParam1.parSecond;
eapEllipseArcParam1.parSecond = tmppar;
}
double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
// reference aux_scratch = LineSeg(x1, y1, x1eps, y1eps, m_curves_style);
// if (aux_scratch) AddObjGroup(m_grpAuxScratches, aux_scratch);
//reference ref = ksEllipseArc(&eapEllipseArcParam);
reference ref = ksParEllipseArc(&eapEllipseArcParam1);
// Equidistant stops after EllipseArc when Nurbs is the next.
// This is workaround - drawing a scratch (LineSeg works fine - BUT must be called near Equidistant?!)
// aux_scratch = LineSeg(x2eps, y2eps, m_BegPoint.x, m_BegPoint.y, m_curves_style);
// if (aux_scratch) AddObjGroup(m_grpAuxScratches, aux_scratch);
return ref;
}
return 0;
}
double CSewingDlg::GetEquidistantPerimeter(reference element) // using destroyObj to get true length of Equidistant
{
int type = GetObjParam(element, 0, 0, ALLPARAM);
if (type != EQUID_OBJ) return 0.0;
double t1, t2;
double x1, y1, x2, y2;
ksGetCurveMinMaxParametr (element, &t1, &t2);
ksGetCurvePoint(element, t1, &x1, &y1);
ksGetCurvePoint(element, t2, &x2, &y2);
double perimeter = 0.0; // ksDistancePntPntOnCurve(element, x1, y1, x2, y2);
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document (for KAPI5 usage)
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
if (!doc7) { Message("No document open - approx"); return 0; }
reference a_group = NewGroup(1);
EndGroup();
if (a_group && AddObjGroup(a_group, element) )
{
// Creating doc for building of nurbs approximation
DocumentParamT parDocument;
memset( &parDocument, 0, sizeof( parDocument ) );
parDocument.regim = 1; // hidden mode
parDocument.type = 3;
reference tmp_doc = CreateDocumentT( &parDocument ); // fragment creation
reference b_group = CopyGroupToDocument(a_group, m_pKompasDoc5->reference, tmp_doc);
StoreTmpGroup( b_group );
if (ExistGroupObj(b_group)) {
reference elem = 0;
do { // pseudo-cycle to destruct tempRasters BEFORE doc-switching & CloseDocument()
KompasIteratorHolder tempApprox(CreateIterator(ALL_OBJ, 0)); // GetViewReference(0)));
if(!tempApprox) break;
elem = MoveIterator(tempApprox, 'F');
} while (0);
ksDestroyObjects(elem);
if (b_group) DeleteObj(b_group);
}
reference c_group = NewGroup(1);
EndGroup();
SelectGroup(c_group, 2, 0,0,0,0);
reference n_group = 0;
if (ExistGroupObj(c_group))
{
KompasIteratorHolder contour_iterator(CreateIterator(ALL_OBJ, c_group));
reference cur_obj_reference = MoveIterator(contour_iterator, 'F');
while (cur_obj_reference)
{
int type = GetObjParam(cur_obj_reference, 0, 0, ALLPARAM);
perimeter += ksGetCurvePerimeter (cur_obj_reference, ST_MIX_MM);
cur_obj_reference = MoveIterator(contour_iterator, 'N');
}
}
if (c_group) DeleteObj(c_group);
//doc7->Active = TRUE;
doc7->Application->ActiveDocument = doc7;
if (tmp_doc) CloseDocument(tmp_doc);
}
return perimeter;
}
reference CSewingDlg::DrawEquidistant(EquidistantParam *equiparam, bool swapped) // new API5 version
{
Message("DrawEquidistant");
return 0;
}
reference CSewingDlg::DrawEquidistant7(IDrawingObjectPtr& idcContour, EquidistantParam *equiparam, bool swapped) // new API7 version
{
//return Equidistant(equiparam);
Message("DrawEquidistant7 -> ");
if (idcContour == 0) return 0;
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
IKompasDocument2DPtr pkdDocument = 0;
doc7->QueryInterface(&pkdDocument);
IViewPtr ivpView = pkdDocument->ViewsAndLayersManager->Views->View[0];
IDrawingContainerPtr pdcContainer = 0;
ivpView->QueryInterface(&pdcContainer);
IDrawingObjectPtr pdoDrawingObject = 0;
ivpView->QueryInterface(&pdoDrawingObject);
IEquidistantsPtr Equidistant_pool = pdcContainer->Equidistants;
IEquidistantPtr Equidistant_curve = Equidistant_pool->Add();
IDrawingObjectPtr idoDrawingContour = idcContour;
reference base_object = idoDrawingContour->Reference;
//reference base_object = equiparam->geoObj;
//IDrawingObjectPtr drawing_object = ksTransferReference( base_object, 0 );
bool bad_state = false;
int type = idoDrawingContour->Type;
if (type == ksObjectDrawingContour)
{
IContourPtr icontour = idoDrawingContour; // ksTransferReference(p_equiparam->geoObj, 0);
if (icontour) {
int icount = icontour->Count;
if (icount < equi_curves_count) bad_state = true;
if (bad_state)
Message("DrawEquidistant7: ERROR building contour!");
// if (bad_state == false && ref5 && (m_issingle ||
// (ksIsCurveClosed(ref5) && ksIsCurveClosed(p_equiparam->geoObj)) )) return ref5;
}
}
BOOL isok = false;
BOOL test_isok = false;
Equidistant_curve->DegenerateSegment = equiparam->degState == 0? FALSE : TRUE;
do {
Equidistant_curve->BaseObject = idoDrawingContour;
Equidistant_curve->CutMode = equiparam->cutMode == 0? FALSE : TRUE;
Equidistant_curve->LeftRadius = equiparam->radLeft;
Equidistant_curve->RightRadius = equiparam->radRight;
Equidistant_curve->Side = equiparam->side == 2? ksETBoth :
equiparam->side == 0? ksETLeft : equiparam->side == 1? ksETRight : ksETUnknown;
Equidistant_curve->Style = equiparam->style; // = ksCSConstruction; // = 6
isok = Equidistant_curve->Update();
//pdoDrawingObject->LayerNumber = pdoDrawingObject->LayerNumber;
//if (!pdoDrawingObject->Update()) Message("NO update");
if (!isok) {
Equidistant_curve->DegenerateSegment = TRUE;
//Equidistant_curve->CutMode = TRUE;
}
isok = isok || test_isok;
test_isok = true;
} while (!isok);
reference ref = Equidistant_curve->Reference;
//if (type == ksObjectDrawingContour || m_issingle)
if (m_issingle)
{
if (bad_state == false && ref && (m_issingle || ksIsCurveClosed(ref))) return ref;
}
double radWorked = Equidistant_curve->Side == ksETLeft? Equidistant_curve->LeftRadius :
Equidistant_curve->Side == ksETRight? Equidistant_curve->RightRadius :
std::max(Equidistant_curve->LeftRadius, Equidistant_curve->RightRadius);
//Message("BUILD equidistant -> ");
if (isok && ref != 0 && bad_state == false) {
double perimeter = ksGetCurvePerimeter (ref, ST_MIX_MM); // always 0!
double summed_len = 0.0;
if (perimeter == 0)
perimeter = GetEquidistantPerimeter(ref);
for (int i = 0; i < equi_curves.size(); i++)
summed_len += ksGetCurvePerimeter (equi_curves[i], ST_MIX_MM);
// may be stuff dealing with wrong perimeter...
if (Equidistant_curve->Side != ksETBoth)
bad_state = std::abs(perimeter - summed_len) > equi_curves_count * (2.*3.20) * radWorked; //about 2*pi
else // ksETBoth
bad_state = std::abs(perimeter - 2 * summed_len) > 2. * 1 * (2.*3.20) * radWorked;
//bad_state = std::abs(perimeter - 2 * summed_len) > 2. * equi_curves_count * (2.*3.20) * radWorked;
}
// API7 version writes Equidistant into object level! (as it looks?)
if (bad_state) // redrawing separately
{
//if (Equidistant_curve) Equidistant_curve->Delete(); //? KEEP it for detecting Contours nesting...
if (Equidistant_curve && ref) AddObjGroup(m_grpAuxScratches, ref);
double t1, t2;
double x1, y1, x2, y2;
ksGetCurveMinMaxParametr (equi_curves[0], &t1, &t2);
ksGetCurvePoint(equi_curves[0], t1, &x1, &y1);
ksGetCurvePoint(equi_curves[0], t2, &x2, &y2);
m_BegPoint.x = x1, m_BegPoint.y = y1;
if (swapped) m_BegPoint.x = x2, m_BegPoint.y = y2;
reference ret_ref = 0;
m_skip_scratch = true;
for (int i = 0; i < equi_curves.size(); i++)
{
//m_pKompasDoc5->ksContour(1);
//Contour(1);
reference obj = 0;
obj = Draw2DElement(equi_curves[i]);
//reference ref5 = m_pKompasDoc5->ksEndObj();
IDrawingObjectPtr idoObject = obj? ksTransferReference(obj, 0) : 0;
if (obj && idoObject) {
IEquidistantPtr Equid_curve = Equidistant_pool->Add();
Equid_curve->BaseObject = idoObject;
Equid_curve->CutMode = equiparam->cutMode == 0? FALSE : TRUE;
Equid_curve->LeftRadius = equiparam->radLeft;
Equid_curve->RightRadius = equiparam->radRight;
Equid_curve->Side = equiparam->side == 2? ksETBoth :
equiparam->side == 0? ksETLeft : equiparam->side == 1? ksETRight : ksETUnknown;
Equid_curve->Style = equiparam->style; // = ksCSConstruction; // = 6
Equid_curve->DegenerateSegment = equiparam->degState == 0? FALSE : TRUE;
isok = Equid_curve->Update();
if (isok == false) {
Equid_curve->BaseObject = idoObject;
Equid_curve->CutMode = equiparam->cutMode == 0? FALSE : TRUE;
Equid_curve->LeftRadius = equiparam->radLeft;
Equid_curve->RightRadius = equiparam->radRight;
Equid_curve->Side = equiparam->side == 2? ksETBoth :
equiparam->side == 0? ksETLeft : equiparam->side == 1? ksETRight : ksETUnknown;
Equid_curve->Style = equiparam->style; // = ksCSConstruction; // = 6
Equid_curve->DegenerateSegment = TRUE;
isok = Equid_curve->Update();
}
ref = Equid_curve->Reference;
DeleteObj(obj);
if (ref == 0) Equid_curve->Delete();
}
if (ret_ref == 0 && ref) ret_ref = ref;
}
m_skip_scratch = false;
return ret_ref;
}
return ref; //? if (!ref) Message("ref == 0"); => ref may be 0!
}
reference CSewingDlg::DrawBezierWithNurbs(reference element, bool closed) // new API7 version
{
#if defined(DO_DEBUG)
//Message("DrawBezierWithNurbs");
#endif
IBezierPtr pBezier = ksTransferReference(element, 0);
if (!pBezier) return 0;
/* VARIANT varAllPoints;
VariantInit(&varAllPoints);
varAllPoints = pBezier->GetPoints(TRUE);
V_VT(&varAllPoints) = VT_ARRAY | VT_R8;*/
//AllPoints = pBezier->GetPoints(AllPoints);
//VARIANT_BOOL boo = AllPoints.boolVal;
BezierParam bpBezierParam;
if (GetObjParam(element, &bpBezierParam, sizeof(BezierParam), ALLPARAM))
{
const int basepoint_count = GetArrayCount(bpBezierParam.pMathPoint);
if (bpBezierParam.pMathPoint == 0 || basepoint_count == 0) return 0;
ASSERT(pBezier->PointsCount == basepoint_count)
std::vector<double> old_Points;
MathPointParam mpMathPoint;
for (int i = 0; i < basepoint_count; i++) {
GetArrayItem(bpBezierParam.pMathPoint, i, &mpMathPoint, sizeof(MathPointParam));
old_Points.push_back(mpMathPoint.x);
old_Points.push_back(mpMathPoint.y);
}
GetArrayItem(bpBezierParam.pMathPoint, 0, &mpMathPoint, sizeof(MathPointParam));
double x = mpMathPoint.x,
y = mpMathPoint.y;
double xn, yn;
bool swapped = false;
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
const bool closed_path = (bpBezierParam.closed != 0 && closed);
if (!closed_path) {
GetArrayItem(bpBezierParam.pMathPoint, basepoint_count - 1, &mpMathPoint, sizeof(MathPointParam));
xn = mpMathPoint.x, yn = mpMathPoint.y;
swapped = CheckSwapBegPoint(x, y, xn, yn);
}
const int degree = 3 + 1;
NurbsPointParam npPoint;
//double base1X, base1Y, left1X, left1Y, right1X, right1Y;
double base2X, base2Y, left2X, left2Y, right2X, right2Y, Weight;
//BezierPointParam par;
//Bezier(closed, 1);
//_Bezier() may be better?
int step = 1;
int split_number = std::max(m_MaxSplitNum, degree);
IMath2DPtr mathp = newKompasAPI->Application->Math2D;
int real_count = 0;
std::vector<double> Points;
std::vector<double> Weights;
std::vector<double> Knots;
//SAFEARRAY * pSrc = V_ARRAY(&varAllPoints);
do {
if (basepoint_count > split_number) step = basepoint_count / split_number;
NurbsPointParam par;
//swapped = false;
if (swapped == false || closed_path)
{
for (int basepoint = 0; basepoint < basepoint_count + step-1; basepoint += step)
{
if (basepoint >= basepoint_count) basepoint = basepoint_count - 1;
GetArrayItem(bpBezierParam.pMathPoint, basepoint, &mpMathPoint, sizeof(MathPointParam));
// this works too!
pBezier->GetPoint(basepoint, &base2X, &base2Y, &left2X, &left2Y, &right2X, &right2Y);
/*
LONG i = 6 * basepoint + 0, j = 6 * basepoint + 1; // B,L,R -> L,B,R !
::SafeArrayGetElement( pSrc, &i, &left2X);
::SafeArrayGetElement( pSrc, &j, &left2Y);
i += 2, j += 2;
::SafeArrayGetElement( pSrc, &i, &base2X);
::SafeArrayGetElement( pSrc, &j, &base2Y);
i += 2, j += 2;
::SafeArrayGetElement( pSrc, &i, &right2X);
::SafeArrayGetElement( pSrc, &j, &right2Y);
*/
ASSERT(mpMathPoint.x == base2X && mpMathPoint.y == base2Y)
//real_count++;
if (basepoint == 0)
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y),
Points.push_back(right2X), Points.push_back(right2Y);
else if (basepoint == basepoint_count - 1 && closed_path == false)
Points.push_back(left2X), Points.push_back(left2Y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y);
else
Points.push_back(left2X), Points.push_back(left2Y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y), // doubling inner point!
Points.push_back(right2X), Points.push_back(right2Y),
Weights.push_back(1.0), Weights.push_back(1.0); // doubling inner point!
Weights.push_back(1.0);
Weights.push_back(1.0);
}
if (closed_path) {
pBezier->GetPoint(0, &base2X, &base2Y, &left2X, &left2Y, &right2X, &right2Y);
//real_count++;
Points.push_back(left2X), Points.push_back(left2Y),
Points.push_back(base2X), Points.push_back(base2Y);
Weights.push_back(1.0);
Weights.push_back(1.0);
}
} else {
//Message("Bezier swapped");
for (int basepoint = basepoint_count - 1; basepoint > -step; basepoint -= step)
{
if (basepoint < 0) basepoint = 0;
GetArrayItem(bpBezierParam.pMathPoint, basepoint, &mpMathPoint, sizeof(MathPointParam));
pBezier->GetPoint(basepoint, &base2X, &base2Y, &left2X, &left2Y, &right2X, &right2Y);
/*
LONG i = 6 * basepoint + 0, j = 6 * basepoint + 1; // B,L,R -> L,R,B !
::SafeArrayGetElement( pSrc, &i, &left2X);
::SafeArrayGetElement( pSrc, &j, &left2Y);
i += 2, j += 2;
::SafeArrayGetElement( pSrc, &i, &base2X);
::SafeArrayGetElement( pSrc, &j, &base2Y);
i += 2, j += 2;
::SafeArrayGetElement( pSrc, &i, &right2X);
::SafeArrayGetElement( pSrc, &j, &right2Y);
*/
ASSERT(mpMathPoint.x == base2X && mpMathPoint.y == base2Y)
//real_count++;
if (basepoint == 0)
Points.push_back(right2X), Points.push_back(right2Y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y);
else if (basepoint == basepoint_count - 1)
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y),
Points.push_back(left2X), Points.push_back(left2Y);
else
Points.push_back(right2X), Points.push_back(right2Y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y),
Points.push_back(mpMathPoint.x), Points.push_back(mpMathPoint.y), // doubling inner point!
Points.push_back(left2X), Points.push_back(left2Y),
Weights.push_back(1.0), Weights.push_back(1.0); // doubling inner point!
Weights.push_back(1.0);
Weights.push_back(1.0);
}
}
real_count = Weights.size(); // = Points.size() / 2;
SAFEARRAYBOUND sabNewArray;
sabNewArray.cElements = real_count * 2;
sabNewArray.lLbound = 0;
SAFEARRAY * pSafe = ::SafeArrayCreate( VT_R8, 1, &sabNewArray );
for (LONG i = 0; i < (LONG)sabNewArray.cElements; i += 2)
{
LONG i0 = i;
::SafeArrayPutElement( pSafe, &i0, &Points[i + 0]); i0++;
::SafeArrayPutElement( pSafe, &i0, &Points[i + 1]);
}
VARIANT varRow;
VariantInit(&varRow);
V_VT(&varRow) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow) = pSafe;
SAFEARRAYBOUND sabNewArray1;
sabNewArray1.cElements = real_count;
sabNewArray1.lLbound = 0;
SAFEARRAY * pSafe1 = ::SafeArrayCreate( VT_R8, 1, &sabNewArray1 );
for (LONG i = 0; i < (LONG)sabNewArray1.cElements;)
{
::SafeArrayPutElement( pSafe1, &i, &Weights[ i ]); i++;
}
VARIANT varRow1;
VariantInit(&varRow1);
V_VT(&varRow1) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow1) = pSafe1;
VARIANT varRow2;
VariantInit(&varRow2);
SAFEARRAYBOUND sabNewArray2;
SAFEARRAY * pSafe2 = 0;
//Message("test0");
if (Knots.size() == 0 && real_count >= degree) { // always
sabNewArray2.cElements = real_count + degree;
sabNewArray2.lLbound = 0;
pSafe2 = ::SafeArrayCreate( VT_R8, 1, &sabNewArray2 );
for (LONG i = 0; i < (LONG)sabNewArray2.cElements; i++)
{
// double data = i < degree? 0.0 : i >= real_count ? 1.0 : double(i - degree + 1) / (real_count - degree + 1) ;
double data = (i / 4); // 0, 1, ... , max = [(real_count + degree) / 4 - 1]
::SafeArrayPutElement( pSafe2, &i, &data);
Knots.push_back(data);
}
}
V_VT(&varRow2) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow2) = pSafe2;
//ICurve2DPtr temp_curve = mathp->Nurbs(closed_path, degree, varRow, varRow1, varRow2);
ICurve2DPtr temp_curve;
//? Closed bezier gives fault!
temp_curve = mathp->Nurbs((closed_path? FALSE : FALSE), degree, varRow, varRow1, varRow2);
/* VARIANT uvarRow;
VariantInit(&uvarRow);
VARIANT uvarRow1;
VariantInit(&uvarRow1);
VARIANT uvarRow2;
VariantInit(&uvarRow2);
double tmin, tmax;
temp_curve->GetNurbsParams(FALSE, &uvarRow, &uvarRow1, &uvarRow2, &tmin, &tmax);
*/
reference rr = temp_curve->Reference; //0!
//temp_curve->Release(); BAD!
double delta = CurvesDeviation(element, temp_curve, m_precision * m_MmToUnits, &old_Points[0], basepoint_count);
if (delta <= m_precision * m_MmToUnits || step == 1) break;
//Message("test");
split_number = std::max(split_number * 2, degree);
{
real_count = 0;
Points.clear();
Weights.clear();
Knots.clear();
}
} while (step > 1);
reference new_curve = 0;
do {
NurbsPointParam par;
//Nurbs(degree, closed_path, 1);
Nurbs(degree, false, 1); //? Closed bezier gives error in Equidistant!
//swapped = true;
if (swapped == false || closed_path) {
for (int i = 0; i < real_count; i++)
{
par.x = Points[2 * i];
par.y = Points[2 * i + 1];
par.weight = Weights[i];
NurbsPoint(&par);
}
if (step == 1 && Knots.size() > 0)
for (int knot = 0; knot < (int)Knots.size(); knot ++)
{
ksNurbsKnot(Knots[knot]);
}
}
else {
//Message("NURBS swapped");
for (int i = 0; i < real_count; i++)
{
par.x = Points[2 * i];
par.y = Points[2 * i + 1];
par.weight = Weights[i];
NurbsPoint(&par);
}
if (step == 1 && Knots.size() > 0) {
double knotmax = Knots.back();
for (int knot = Knots.size() - 1; knot >= 0; knot --)
{
double knotdata = Knots[knot];
int res = ksNurbsKnot(knotmax - knotdata);
if (!res) Message("BAD knot");
}
}
}
new_curve = EndObj();
#if defined(DO_DEBUG)
//if (new_curve == 0) Message("DrawBezierWithNurbs returns ref == 0!");
#endif
if (new_curve) return new_curve; // => new_curve may be 0! like for Bezier !?
} while (0);
}
return 0;
}
reference CSewingDlg::DrawBezier(reference element, bool closed) // new API7 version
{
//Message("DrawBezier");
IBezierPtr pBezier = ksTransferReference(element, 0);
if (!pBezier) return 0;
BezierParam bpBezierParam;
int step = 1;
bool swapped = false;
if (GetObjParam(element, &bpBezierParam, sizeof(BezierParam), ALLPARAM))
{
const int basepoint_count = GetArrayCount(bpBezierParam.pMathPoint);
if (bpBezierParam.pMathPoint == 0 || basepoint_count == 0) return 0;
//ASSERT(AllPointsCount == basepoint_count)
MathPointParam mpMathPoint;
GetArrayItem(bpBezierParam.pMathPoint, 0, &mpMathPoint, sizeof(MathPointParam));
double x = mpMathPoint.x,
y = mpMathPoint.y;
double xn, yn;
bool swapped = false;
if (!closed) {
GetArrayItem(bpBezierParam.pMathPoint, basepoint_count - 1, &mpMathPoint, sizeof(MathPointParam));
xn = mpMathPoint.x, yn = mpMathPoint.y;
swapped = CheckSwapBegPoint(x, y, xn, yn);
}
const int split_number = std::max(m_MaxSplitNum, 4);
if (basepoint_count > split_number) step = basepoint_count / split_number;
}
const BOOL Bezier_mode = (step > 1)? FALSE : TRUE;
ULONG AllPointsCount = pBezier->PointsCount,
OutPointsCount = (step == 1)? AllPointsCount :
int((AllPointsCount + step - 1) / step) + ((AllPointsCount % step == 1)? 0 : 1);
//variant_t AllPoints = pBezier->GetPoints(FALSE);
//AllPoints = pBezier->GetPoints(AllPoints);
VARIANT varRow;
VariantInit(&varRow);
varRow = pBezier->GetPoints(Bezier_mode);
V_VT(&varRow) = VT_ARRAY | VT_R8;
// IMath2DPtr MathDrawer = pBezier->Application->Math2D;
// ICurve2DPtr MathCurve = MathDrawer->Bezier(closed, Bezier_mode, varRow);
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document (for KAPI5 usage)
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
IKompasDocument2DPtr pkdDocument = 0;
doc7->QueryInterface(&pkdDocument);
IViewPtr ivpView = pkdDocument->ViewsAndLayersManager->Views->View[0];
IDrawingContainerPtr pdcContainer = 0;
ivpView->QueryInterface(&pdcContainer);
IDrawingObjectPtr pdoDrawingObject = 0;
ivpView->QueryInterface(&pdoDrawingObject);
IBeziersPtr Bezier_pool = pdcContainer->Beziers;
IBezierPtr Bezier_curve = Bezier_pool->Add();
Bezier_curve->Closed = closed;
Bezier_curve->Style = 1;
SAFEARRAYBOUND sabNewArray;
sabNewArray.cElements = OutPointsCount * (Bezier_mode? 6 : 2);
sabNewArray.lLbound = 0;
SAFEARRAY * pSafe = ::SafeArrayCreate( VT_R8, 1, &sabNewArray );
//if (step > 1)
//Message("step > 1");
//swapped = true;
if (swapped == false || closed)//_path)
{
//Message("swapped == false");
SAFEARRAY * pSrc = V_ARRAY(&varRow);
double arrdata;
if (Bezier_mode == FALSE)
for (ULONG i0 = 0, j0 = 0; j0 < sabNewArray.cElements; i0 += 2 * step, j0 += 2)
{
if (i0 >= 2 * AllPointsCount) i0 = 2 * (AllPointsCount - 1);
LONG i = i0, j = j0;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
}
else
{
for (ULONG i0 = 0, j0 = 0; j0 < sabNewArray.cElements; i0 += 6 * step, j0 += 6) // B,L,R -> L,B,R !
{
if (i0 >= 6 * AllPointsCount) i0 = 6 * (AllPointsCount - 1);
LONG i = i0, j = j0 + 2;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i = i0 + 2, j = j0;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i = i0 + 4, j = j0 + 4;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
}
}
VARIANT varRow0;
VariantInit(&varRow0);
V_VT(&varRow0) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow0) = pSafe;
long OldPointsCount = Bezier_curve->PointsCount;
Bezier_curve->PutPoints(Bezier_mode, varRow0);
long NewPointsCount = Bezier_curve->PointsCount;
BOOL istemp = Bezier_curve->Temp;
BOOL isok = Bezier_curve->Update();
}
else
{
//Message("Swapped");
SAFEARRAY * pSrc = V_ARRAY(&varRow);
double arrdata;
if (Bezier_mode == FALSE)
for (ULONG i0 = 0, j0 = 0; j0 < sabNewArray.cElements; i0 += 2 * step, j0 += 2)
{
if (i0 >= 2 * AllPointsCount) i0 = 2 * (AllPointsCount - 1);
LONG i = i0, j = sabNewArray.cElements - j0 - 2;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
}
else
{
for (ULONG i0 = 0, j0 = 0; j0 < sabNewArray.cElements; i0 += 6 * step, j0 += 6) // B,L,R -> L,R,B !
{
if (i0 >= 6 * AllPointsCount) i0 = 6 * (AllPointsCount - 1);
LONG i = i0, j = sabNewArray.cElements - j0 - 2;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i = i0 + 2, j = sabNewArray.cElements - j0 - 6;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i = i0 + 4, j = sabNewArray.cElements - j0 - 4;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
i++, j++;
::SafeArrayGetElement( pSrc, &i, &arrdata);
::SafeArrayPutElement( pSafe, &j, &arrdata);
}
}
VARIANT varRow0;
VariantInit(&varRow0);
V_VT(&varRow0) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow0) = pSafe;
long OldPointsCount = Bezier_curve->PointsCount;
Bezier_curve->PutPoints(Bezier_mode, varRow0);
long NewPointsCount = Bezier_curve->PointsCount;
BOOL istemp = Bezier_curve->Temp;
BOOL isok = Bezier_curve->Update();
}
/*
IUnknownPtr pUnk0 = ksTransferReference( element, 0 );
IDrawingObjectPtr doDrawingObject = NULL;
pUnk0->QueryInterface(&doDrawingObject);
doDrawingObject->LayerNumber = doDrawingObject->LayerNumber;
if (!doDrawingObject->Update()) Message("NO update object");
IDrawingObjectPtr doDrawingObject1 = NULL;
Bezier_curve->QueryInterface(&doDrawingObject1);
doDrawingObject1->LayerNumber = doDrawingObject1->LayerNumber;
if (!doDrawingObject1->Update()) Message("NO update object1");
if (!pdoDrawingObject->Update()) Message("NO update view");*/
reference ref = Bezier_curve->Reference;
PumpWaitingMessages();
//pdoDrawingObject->LayerNumber = pdoDrawingObject->LayerNumber;
//if (!pdoDrawingObject->Update()) Message("NO update object");
//PumpWaitingMessages();
/* VARIANT varRow1;
VariantInit(&varRow1);
varRow1 = pBezier->GetPoints(FALSE);
V_VT(&varRow1) = VT_ARRAY | VT_R8;
std::vector<double> old_points(AllPointsCount * 2);
SAFEARRAY * pSrc1 = V_ARRAY(&varRow1);
for (LONG i = 0; i < (LONG)(2 * AllPointsCount); i++)
{
::SafeArrayGetElement( pSrc1, &i, &old_points[i]);
}
double delta = CurvesDeviation(IDrawingObjectPtr(pBezier), IDrawingObjectPtr(Bezier_curve), &old_points[0], AllPointsCount);
*/
#if defined(DO_DEBUG)
//if (ref == 0) Message("DrawBezier returns ref == 0!");
#endif
return ref; //? if (!ref) Message("ref == 0"); => ref may be 0!
}
reference CSewingDlg::DrawRectangle(reference element)
{
RectangleParam rpRectangleParam;
if (GetObjParam(element, &rpRectangleParam, sizeof(RectangleParam), ALLPARAM))
{
double x = rpRectangleParam.x,
y = rpRectangleParam.y;
double angle = rpRectangleParam.ang;
double w = rpRectangleParam.width,
h = rpRectangleParam.height;
rpRectangleParam.style = 1;
double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
//rpRectangleParam.pCorner = ::CreateArray(CORNER_ARR, 0); // Создание массива параметров углов
return ksRectangle(&rpRectangleParam, 0);
}
return 0;
}
reference CSewingDlg::DrawRegularPolygon(reference element)
{
RegularPolygonParam rppRegularPolygonParam;
if (GetObjParam(element, &rppRegularPolygonParam, sizeof(RegularPolygonParam), ALLPARAM))
{
double xc = rppRegularPolygonParam.xc,
yc = rppRegularPolygonParam.yc;
double angle = rppRegularPolygonParam.ang;
double r = rppRegularPolygonParam.radius;
int sides = rppRegularPolygonParam.count;
int inscribed = rppRegularPolygonParam.describe;
rppRegularPolygonParam.style = 1;
double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
//rppRegularPolygonParam.pCorner = ::CreateArray(CORNER_ARR, 0); // Создание массива параметров углов
return ksRegularPolygon(&rppRegularPolygonParam, 0);
}
return 0;
}
reference CSewingDlg::DrawPolyline(reference element, bool closed)
{
PolylineParamEx ppPolylineParam;
if (GetObjParam(element, &ppPolylineParam, sizeof(PolylineParamEx), ALLPARAM))
{
const int vertex_count = GetArrayCount(ppPolylineParam.pMathPoint);
if (ppPolylineParam.pMathPoint == 0 || vertex_count == 0) return 0;
MathPointParam mpMathPoint;
GetArrayItem(ppPolylineParam.pMathPoint, 0, &mpMathPoint, sizeof(MathPointParam));
double x = mpMathPoint.x,
y = mpMathPoint.y;
double xn, yn;
bool swapped = false;
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
const bool closed_path = (ppPolylineParam.closed != 0);
if (!closed_path) {
GetArrayItem(ppPolylineParam.pMathPoint, vertex_count - 1, &mpMathPoint, sizeof(MathPointParam));
xn = mpMathPoint.x, yn = mpMathPoint.y;
swapped = CheckSwapBegPoint(x, y, xn, yn);
}
ksPolyline(1);
if (swapped == false || closed_path)
for (int vertex = 0; vertex < vertex_count; vertex++)
{
GetArrayItem(ppPolylineParam.pMathPoint, vertex, &mpMathPoint, sizeof(MathPointParam));
Point(mpMathPoint.x, mpMathPoint.y, 0);
}
else
for (int vertex = vertex_count - 1; vertex >= 0; vertex--)
{
GetArrayItem(ppPolylineParam.pMathPoint, vertex, &mpMathPoint, sizeof(MathPointParam));
Point(mpMathPoint.x, mpMathPoint.y, 0);
}
return EndObj();
}
return 0;
}
reference CSewingDlg::DrawContour(reference element, bool closed)
{
return 0;
return DrawApproximation(element, CONTOUR_OBJ);
//DrawProtoContour(element, DeferDrawing, parentDrawingInView);
}
reference CSewingDlg::DrawNurbs(reference element, bool closed) // new API7+IMath2D
{
//Message("DrawNURBS");
INurbsPtr pNurbs = ksTransferReference(element, 0);
if (!pNurbs) return 0;
NurbsParam npNurbsParam;
if (GetObjParam(element, &npNurbsParam, sizeof(NurbsParam), ALLPARAM))
{
std::vector<double> old_Points;
const int basepoint_count = GetArrayCount(npNurbsParam.pPoint);
const int knot_count = GetArrayCount(npNurbsParam.pKnot);
if (npNurbsParam.pPoint == 0 || basepoint_count == 0) return 0;
int degree = npNurbsParam.degree;
NurbsPointParam npPoint;
for (int i = 0; i < basepoint_count; i++) {
GetArrayItem(npNurbsParam.pPoint, i, &npPoint, sizeof(npPoint));
old_Points.push_back(npPoint.x);
old_Points.push_back(npPoint.y);
}
GetArrayItem(npNurbsParam.pPoint, 0, &npPoint, sizeof(npPoint));
double x = npPoint.x,
y = npPoint.y,
w = npPoint.weight;
double xn, yn;
bool swapped = false;
const double perimeter = ksGetCurvePerimeter (element, ST_MIX_MM);
const bool closed_path = (npNurbsParam.close != 0 && closed);
bool knotted = (npNurbsParam.pKnot != 0);
if (!closed_path) {
GetArrayItem(npNurbsParam.pPoint, basepoint_count - 1, &npPoint, sizeof(npPoint));
xn = npPoint.x, yn = npPoint.y;
swapped = CheckSwapBegPoint(x, y, xn, yn);
}
int step = 1;
int split_number = std::max(m_MaxSplitNum, degree);
IMath2DPtr mathp = newKompasAPI->Application->Math2D;
do {
if (basepoint_count > split_number) step = basepoint_count / split_number;
//double base1X, base1Y, left1X, left1Y, right1X, right1Y;
double base2X, base2Y, Weight;
NurbsPointParam par;
//Nurbs(degree, closed, 1);
int real_count = 0;
std::vector<double> Points;
std::vector<double> Weights;
std::vector<double> Knots;
//swapped = true;
if (swapped == false || closed_path) {
for (int basepoint = 0; basepoint < basepoint_count + step-1; basepoint += step)
{
if (basepoint >= basepoint_count) basepoint = basepoint_count - 1;
GetArrayItem(npNurbsParam.pPoint, basepoint, &npPoint, sizeof(npPoint));
pNurbs->GetPoint(basepoint, &base2X, &base2Y, &Weight);
ASSERT(npPoint.x == base2X && npPoint.y == base2Y && npPoint.weight == Weight)
par.x = base2X;
par.y = base2Y;
par.weight = Weight;
real_count++;
Points.push_back(par.x), Points.push_back(par.y);
Weights.push_back(Weight);
}
if (step == 1 && knotted && knot_count > 0)
for (int knot = 0; knot < knot_count + step-1; knot += step)
{
double knotdata;
GetArrayItem(npNurbsParam.pKnot, knot, &knotdata, sizeof(knotdata));
Knots.push_back(knotdata);
}
}
else {
//Message("NURBS swapped");
for (int basepoint = basepoint_count - 1; basepoint > -step; basepoint -= step)
{
if (basepoint < 0) basepoint = 0;
GetArrayItem(npNurbsParam.pPoint, basepoint, &npPoint, sizeof(npPoint));
pNurbs->GetPoint(basepoint, &base2X, &base2Y, &Weight);
ASSERT(npPoint.x == base2X && npPoint.y == base2Y && npPoint.weight == Weight)
par.x = base2X;
par.y = base2Y;
par.weight = Weight;
real_count++;
Points.push_back(par.x), Points.push_back(par.y);
Weights.push_back(Weight);
}
if (step == 1 && knotted && knot_count > 0) {
double knotmax;
GetArrayItem(npNurbsParam.pKnot, knot_count - 1, &knotmax, sizeof(knotmax));
for (int knot = knot_count - 1; knot > -step; knot -= step)
{
double knotdata;
GetArrayItem(npNurbsParam.pKnot, knot, &knotdata, sizeof(knotdata));
Knots.push_back(knotmax - knotdata);
}
}
}
SAFEARRAYBOUND sabNewArray;
sabNewArray.cElements = real_count * 2;
sabNewArray.lLbound = 0;
SAFEARRAY * pSafe = ::SafeArrayCreate( VT_R8, 1, &sabNewArray );
for (LONG i = 0; i < (LONG)sabNewArray.cElements; i += 2)
{
LONG i0 = i;
::SafeArrayPutElement( pSafe, &i0, &Points[i + 0]); i0++;
::SafeArrayPutElement( pSafe, &i0, &Points[i + 1]);
}
VARIANT varRow;
VariantInit(&varRow);
V_VT(&varRow) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow) = pSafe;
SAFEARRAYBOUND sabNewArray1;
sabNewArray1.cElements = real_count;
sabNewArray1.lLbound = 0;
SAFEARRAY * pSafe1 = ::SafeArrayCreate( VT_R8, 1, &sabNewArray1 );
for (LONG i = 0; i < (LONG)sabNewArray1.cElements;)
{
::SafeArrayPutElement( pSafe1, &i, &Weights[ i ]); i++;
}
VARIANT varRow1;
VariantInit(&varRow1);
V_VT(&varRow1) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow1) = pSafe1;
VARIANT varRow2;
VariantInit(&varRow2);
SAFEARRAYBOUND sabNewArray2;
SAFEARRAY * pSafe2 = 0;
//Message("test0");
if (Knots.size() > 0) {
sabNewArray2.cElements = Knots.size();
sabNewArray2.lLbound = 0;
pSafe2 = ::SafeArrayCreate( VT_R8, 1, &sabNewArray2 );
for (LONG i = 0; i < (LONG)sabNewArray2.cElements;)
{
::SafeArrayPutElement( pSafe2, &i, &Knots[ i ]); i++;
}
} else {
sabNewArray2.cElements = real_count + degree;
sabNewArray2.lLbound = 0;
pSafe2 = ::SafeArrayCreate( VT_R8, 1, &sabNewArray2 );
for (LONG i = 0; i < (LONG)sabNewArray2.cElements; i++)
{
double data = i < degree? 0.0 : i > real_count ? 1.0 : double(i) / real_count ;
::SafeArrayPutElement( pSafe2, &i, &data);
}
}
V_VT(&varRow2) = VT_ARRAY | VT_R8;
V_ARRAY(&varRow2) = pSafe2;
//ICurve2DPtr temp_curve = mathp->Nurbs(closed_path, degree, varRow, varRow1, varRow2);
ICurve2DPtr temp_curve;
temp_curve = mathp->Nurbs(closed_path, degree, varRow, varRow1, varRow2);
/* VARIANT uvarRow;
VariantInit(&uvarRow);
VARIANT uvarRow1;
VariantInit(&uvarRow1);
VARIANT uvarRow2;
VariantInit(&uvarRow2);
double tmin, tmax;
temp_curve->GetNurbsParams(FALSE, &uvarRow, &uvarRow1, &uvarRow2, &tmin, &tmax);
*/
reference rr = temp_curve->Reference; //0!
//temp_curve->Release(); BAD!
double delta = CurvesDeviation(element, temp_curve, m_precision * m_MmToUnits, &old_Points[0], basepoint_count);
if (delta <= m_precision * m_MmToUnits) break;
//Message("test");
split_number = std::max(split_number * 2, degree);
} while (step > 1);
reference new_curve = 0;
do {
//double base1X, base1Y, left1X, left1Y, right1X, right1Y;
double base2X, base2Y, Weight;
NurbsPointParam par;
Nurbs(degree, closed, 1);
int real_count = 0;
//swapped = true;
if (swapped == false || closed_path) {
for (int basepoint = 0; basepoint < basepoint_count + step-1; basepoint += step)
{
if (basepoint >= basepoint_count) basepoint = basepoint_count - 1;
GetArrayItem(npNurbsParam.pPoint, basepoint, &npPoint, sizeof(npPoint));
pNurbs->GetPoint(basepoint, &base2X, &base2Y, &Weight);
ASSERT(npPoint.x == base2X && npPoint.y == base2Y && npPoint.weight == Weight)
par.x = base2X;
par.y = base2Y;
par.weight = Weight;
NurbsPoint(&par);
real_count++;
}
if (step == 1 && knotted && knot_count > 0)
for (int knot = 0; knot < knot_count + step-1; knot += step)
{
double knotdata;
GetArrayItem(npNurbsParam.pKnot, knot, &knotdata, sizeof(knotdata));
ksNurbsKnot(knotdata);
}
}
else {
//Message("NURBS swapped");
for (int basepoint = basepoint_count - 1; basepoint > -step; basepoint -= step)
{
if (basepoint < 0) basepoint = 0;
GetArrayItem(npNurbsParam.pPoint, basepoint, &npPoint, sizeof(npPoint));
pNurbs->GetPoint(basepoint, &base2X, &base2Y, &Weight);
ASSERT(npPoint.x == base2X && npPoint.y == base2Y && npPoint.weight == Weight)
par.x = base2X;
par.y = base2Y;
par.weight = Weight;
NurbsPoint(&par);
real_count++;
}
if (step == 1 && knotted && knot_count > 0) {
double knotmax;
GetArrayItem(npNurbsParam.pKnot, knot_count - 1, &knotmax, sizeof(knotmax));
for (int knot = knot_count - 1; knot > -step; knot -= step)
{
double knotdata;
GetArrayItem(npNurbsParam.pKnot, knot, &knotdata, sizeof(knotdata));
int res = ksNurbsKnot(knotmax - knotdata);
if (!res) Message("BAD knot");
}
}
}
new_curve = EndObj();
#if defined(DO_DEBUG)
//if (new_curve == 0) Message("DrawNurbs returns ref == 0!");
#endif
if (new_curve) return new_curve; // => new_curve may be 0! like for Bezier !?
} while (0);
}
return 0;
//return DrawApproximation(element, NURBS_OBJ);
//DrawNurbsAsContour(element);
}
double CSewingDlg::CurvesDeviation(reference old_curve, ICurve2DPtr& new_curve, double precision, double* tpars, int points_count)
{
// return 0;
//Message("CurvesDeviation!");
double delta = 0.0, average = 0.0;
double x, y, kx, ky, t, angle, data;
int count = 0;
for (int i = 0; i < points_count; i++) {
x = tpars[2 * i];
y = tpars[2 * i + 1];
::ksGetCurvePointProjection (old_curve, x, y, &x, &y);
//if (new_curve->PointProjection(x, y, &kx, &ky, &t, &angle)) BAD KOPAS - returns FALSE when success
new_curve->PointProjection(x, y, &kx, &ky, &t, &angle);
data = DistancePntPnt(x, y, kx, ky),
delta = std::max(delta, data),
average += data, count++;
if (delta > precision) return delta; // to speed up this loop
}
if (count > 0)average /= count;
return delta;
}
reference CSewingDlg::DrawApproximation(reference element, int curve_type)
{
Message("DrawApproximation");
if (curve_type != CONTOUR_OBJ) return 0;
return 0;
}
// structs declared on local level to debug in VC-debugger (MS bug)
struct Edge {
double x1; double y1;
double x2; double y2;
reference curve;
size_t node_index1; // aux field denotes Index of vertex 1 (ordered from 1; 0 means UNDEFINED)
size_t node_index2; // aux field denotes Index of vertex 2 (ordered from 1; 0 means UNDEFINED)
size_t link_index; // aux vertex/edge component index, used later as work field (1-ordered; 0 means UNDEFINED)
size_t back_index1, back_index2, back_count; // back indexes for special case
Edge(double ux1, double uy1, double ux2, double uy2, reference ucurve)
: x1(ux1), y1(uy1), x2(ux2), y2(uy2), curve(ucurve), link_index(0), node_index1(0), node_index2(0)
,back_count(0), back_index1(0), back_index2(0) {}
};
struct CurveType {
unsigned short style;
unsigned long color;
double width;
std::vector<Edge> Curves;
CurveType(unsigned short ustyle, unsigned long ucolor, double uwidth)
: style(ustyle), color(ucolor), width(uwidth) {}
};
struct LineEnd {
double x; double y;
size_t index; // index into Curves (ordered from 1; 0 means UNDEFINED)
size_t single_loop; // special case
LineEnd(double ux, double uy, size_t uindex) : x(ux), y(uy), index(uindex), single_loop(0) {}
//static bool SortedX (const LineEnd & lthis, const LineEnd & lend) { return lthis.x < lend.x; }
static bool SortedYpostX (const LineEnd & lthis, const LineEnd & lend) { return equal_values(lthis.x, lend.x)? (lthis.y < lend.y) : (lthis.x < lend.x); }
};
struct Node {
double x; double y;
size_t edge_index; // (ordered from 1; 0 means UNDEFINED)
size_t node_index; // aux field denotes Index of vertex (ordered from 1; 0 means UNDEFINED)
size_t link_index; // aux field used later to detect components (ordered from 1; 0 means UNDEFINED)
Node(double ux, double uy, size_t uindex) : x(ux), y(uy), edge_index(uindex), node_index(0), link_index(0) {}
Node(double ux, double uy, size_t uindex, size_t uNindex, size_t uLindex) : x(ux), y(uy), edge_index(uindex), node_index(uNindex), link_index(uLindex) {}
};
struct NodeLinks {
Node thisNode;
size_t edge_count; // aux count
size_t parent_index; // aux index (ordered from 1; 0 means UNDEFINED)
size_t inner_edge_index; // aux index (ordered from 1; 0 means UNDEFINED)
std::vector<Node> Nodes;
NodeLinks(Node& uNode) : thisNode(uNode.x, uNode.y, uNode.edge_index, uNode.node_index, uNode.link_index),
edge_count(0), parent_index(0), inner_edge_index(0) {}
};
struct equi_contour {
reference contour;
reference parent;
bool issingle;
bool swapped_curve;
std::vector <reference> equi_curves;
int equi_curves_count; // may differ from equi_curves.size() due to m_grpAuxScratches
int enclose_count; // testing or SLOW VERSION
static CSewingDlg* pThis;
equi_contour(reference r, bool single, bool swapped, std::vector <reference>& curves, int curves_count)
: contour(r), issingle(single), swapped_curve(swapped), parent(0), enclose_count(0), equi_curves_count(curves_count)
{
if (curves.size() > 0) equi_curves.insert(equi_curves.begin(), curves.begin(), curves.end());
}
static bool SortedContours (const equi_contour & lthis, const equi_contour & lend) {
if (lthis.parent && !lend.parent) return true;
//if (lthis.parent && lend.parent) return IsContourInsideContour(lthis.parent, lend.parent, pThis);
return IsContourInsideContour(lthis.contour, lend.contour, pThis); }
};
CSewingDlg* equi_contour::pThis = 0;
void CSewingDlg::PrepareContoursMakeEquidistants(reference obj_iterator, EquidistantParam *equiparam)
{
std::vector<CurveType> locCurvesPool;
//ATTENTION - decomposed_reference group & iterator MUST be kept int tmp group HERE for docomposed objects be valid!
// reference rGroup = NewGroup(1);
// EndGroup();
do { // cycle to collect from view objects (no need if part_reference is some else but view)
reference cur_object_reference = MoveIterator(obj_iterator, 'F');
ksCurveStyleParamPtr styleParam = kompasAPI->GetParamStruct(ko_CurveStyleParam);
while (cur_object_reference)
{
int type = GetObjParam(cur_object_reference, 0, 0, ALLPARAM);
int obj_style = ksGetObjectStyle(cur_object_reference);
//bool accepted = (type == LINESEG_OBJ || type == ARC_OBJ) && obj_style != CURVE_AXIS3_SPECIAL; // decomposition produces only these types!
bool accepted = (type != 0 && type != EQUID_OBJ && (type != LINESEG_OBJ || obj_style != EQUI_STYLE));
bool approxed = (type == CONTOUR_OBJ);//?? || type == BEZIER_OBJ); // || type == NURBS_OBJ);
do { // pseudocycle to handle special breakes
if (!ExistObj( cur_object_reference ) || !IsGeomObject( cur_object_reference )) break;
if (accepted == false || approxed) break;
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document (for KAPI5 usage)
if (m_pKompasDoc5->ksGetStyleParam(CURVE_STYLE_EX, (short)obj_style, styleParam) == 0) break;
double t1, t2, x1, y1, x2, y2;
ksGetCurveMinMaxParametr (cur_object_reference, &t1, &t2);
ksGetCurvePoint(cur_object_reference, t1, &x1, &y1);
ksGetCurvePoint(cur_object_reference, t2, &x2, &y2);
//if ((m_SaveViewMatricesPdfMode > 0 || m_EMULATION_state == false)) //? && m_CurrentViewIndex != 0)
{
ksPointIntoMtr (x1, y1, &x1, &y1);
ksPointIntoMtr (x2, y2, &x2, &y2);
}
if (m_ContourHasAnyLineStyles != 0) {
if (locCurvesPool.size() == 0) locCurvesPool.push_back(CurveType(0, 0, 0));
locCurvesPool[0].Curves.push_back(Edge(x1, y1, x2, y2, cur_object_reference));
continue;
}
bool found = false;
for (size_t i = 0; i < locCurvesPool.size(); i++)
{
if (obj_style == locCurvesPool[i].style && styleParam->color == locCurvesPool[i].color && styleParam->paperWidth == locCurvesPool[i].width)
{
locCurvesPool[i].Curves.push_back(Edge(x1, y1, x2, y2, cur_object_reference));
found = true; break;
}
}
if (!found) {
locCurvesPool.push_back(CurveType(obj_style, styleParam->color, styleParam->paperWidth));
locCurvesPool[locCurvesPool.size()-1].Curves.push_back(Edge(x1, y1, x2, y2, cur_object_reference));
}
} while (0);
if (!IsGeomObject( cur_object_reference ) || accepted == false)
{
//SKIP! //Draw2DElement(cur_object_reference); // drawing texts
}
cur_object_reference = MoveIterator(obj_iterator, 'N');
}
} while (0); //while (needIterator && part_reference != 0);
CWnd * pCWnd = NULL;
pCWnd = CWnd::FromHandlePermanent( (HWND) GetHWindow() );
if (! pCWnd) pCWnd = CWnd::FromHandle( (HWND) GetHWindow() ); // GetActiveWindow() ?
if (! pCWnd) pCWnd = CWnd::FromHandle( ::GetActiveWindow() ); // (HWND)GetHWindow()
progress_object = new CProgressDlg( pCWnd );
glb_Interrupt = FALSE;
progress_object->Create(IDD_PROGRESSDLG, pCWnd); // Show dialog
progress_object->ShowWindow(SW_SHOWNORMAL); // Show dialog
// progress_object->ShowWindow(SW_HIDE); // Show dialog
((CProgressCtrl*)progress_object->GetDlgItem( IDC_PROGRESS ))->SetRange32(0, std::max(0, 1));
Message("DONE COLLECTING...");
ksSetProgressText("Обработка эквидистант...");
int contours_count = PseudoProcessAcceptedData(&locCurvesPool, 0, false);
//Message("DONE COUNT...");
if (contours_count == 0)
{
progress_object->DestroyWindow();
progress_object = NULL;
PumpWaitingMessages();
Message("Ничего не выбрано или чертеж пуст.");
return;
}
#if defined(DO_DEBUG) == 0 //LICENCING!
//MESSAGE(L"LICENCING contours_count = %d" MESSAGE_COMMA contours_count)
if (contours_count > 10 || m_SelectType == enCurves_All)
{
PumpWaitingMessages();
Message("Данная демо-версия плагина не имеет блока определения\n"
"множества контуров и будет работать только с 10 контурами\n"
"или связанными компонентами.\n"
"Для работы с многими контурами (полнофункциональным плагином)\n"
"вам необходимо получить лицензию в компании Gkmsoft (gkmsoft.ru)");
if (m_SelectType == enCurves_All) {
progress_object->DestroyWindow();
progress_object = NULL;
return;
}
}
#endif
((CProgressCtrl*)progress_object->GetDlgItem( IDC_PROGRESS ))->SetRange32(0, std::max(0, contours_count-1));
ksStartProgressBar(0, contours_count, "Обработка эквидистант...", 1);
PseudoProcessAcceptedData(&locCurvesPool, equiparam, false);
//Message("DONE ALL...");
ksStopProgressBar("Операция завершена.", 1);
PumpWaitingMessages();
progress_object->DestroyWindow();
progress_object = NULL;
}
int CSewingDlg::PseudoProcessAcceptedData(void* pInputData, EquidistantParam *equiparam, bool PseudoGroupMode)
{
std::vector<CurveType>& locCurvesPool = *(std::vector<CurveType>*)pInputData;
//PARSING TEST
for (size_t i = 0; i < locCurvesPool.size(); i++)
{
unsigned short style = locCurvesPool[i].style;
unsigned long color = locCurvesPool[i].color;
double width = locCurvesPool[i].width;
//std::vector<Edge>& Edges = locCurvesPool[i].Curves;
size_t nodes_size = locCurvesPool[i].Curves.size();
for (size_t j = 0; j < locCurvesPool[i].Curves.size(); j++)
{
//if (locCurvesPool[i].Curves[j].curve == 0) continue;
double x1 = locCurvesPool[i].Curves[j].x1;
double y1 = locCurvesPool[i].Curves[j].y1;
double x2 = locCurvesPool[i].Curves[j].x2;
double y2 = locCurvesPool[i].Curves[j].y2;
reference curve = locCurvesPool[i].Curves[j].curve;
int type = GetObjParam(curve, 0, 0, ALLPARAM);
curve = curve;
}
}
bool contours_left = true;
int contours_count = 0;
bool count_mode = (equiparam == 0);
// optimizing vertices (sorting)
for (size_t ii0 = 0, contours_left = true; ii0 < locCurvesPool.size(); ii0++, contours_left = true)
{
/* struct equi_contour {
reference contour;
bool issingle;
equi_contour(reference r, bool single) : contour(r), issingle(single) {}
static bool SortedContours (const equi_contour & lthis, const equi_contour & lend) {
return IsContourInsideContour(lthis.contour, lend.contour); }
};*/
std::vector<Edge> CurvesCopy;
if (count_mode)
CurvesCopy.insert(CurvesCopy.begin(), locCurvesPool[ii0].Curves.begin(), locCurvesPool[ii0].Curves.end());
std::vector <equi_contour> equi_contours;
//std::vector <reference> equi_curves; // tmp vector
m_curves_style = 1; // = locCurvesPool[i].style;
m_grpAuxScratches = NewGroup(0);
EndGroup();
for (size_t ii = 0; contours_left; ii++) // additional passes to resolve lost branches and draw one contour in a pass (no more than 1+CONTOURS)
{ // where CONTOURS = (EDGES + COMPONENTS - VERTICES) by Euler formula
/* struct LineEnd {
double x; double y;
size_t index; // index into Curves (ordered from 1; 0 means UNDEFINED)
LineEnd(double ux, double uy, size_t uindex) : x(ux), y(uy), index(uindex) {}
//static bool SortedX (const LineEnd & lthis, const LineEnd & lend) { return lthis.x < lend.x; }
static bool SortedYpostX (const LineEnd & lthis, const LineEnd & lend) { if (equal_values(lthis.x, lend.x)) return lthis.y < lend.y; return lthis.x < lend.x; }
};*/
std::vector<Edge>& LineEnds = count_mode? CurvesCopy : locCurvesPool[ii0].Curves;
std::vector<LineEnd> EndsX;
// std::vector<LineEnd> EndsY;
for (size_t j = 0; j < LineEnds.size(); j++)
{
//LineEnds[j].curve = 0;
LineEnds[j].link_index = LineEnds[j].node_index1 = LineEnds[j].node_index2 = 0;
LineEnds[j].back_count = LineEnds[j].back_index1 = LineEnds[j].back_index2 = 0;
double x1 = LineEnds[j].x1;
double y1 = LineEnds[j].y1;
EndsX.push_back(LineEnd(x1, y1, (j + 1))); // (ordered from 1!)
double x2 = LineEnds[j].x2;
double y2 = LineEnds[j].y2;
EndsX.push_back(LineEnd(x2, y2, (j + 1))); // (ordered from 1!)
}
if (ii == 0 && ii0==1)
{
for (size_t j = 0; j < LineEnds.size(); j++)
{
// if (LineEnds[j].link_index == 0)
double x1 = LineEnds[j].x1, y1 = LineEnds[j].y1;
double x2 = LineEnds[j].x2, y2 = LineEnds[j].y2;
//if (j+1 == 30 || j+1 == 28 || j+1 == 31)
// LineSeg(x1+360, y1-5, x2+360, y2-5, 6);
}
}
// EndsY.insert(EndsY.begin(), EndsX.begin(), EndsX.end());
//?std::sort(EndsX.begin(), EndsX.end(), LineEnd::SortedX);
// std::sort(EndsY.begin(), EndsY.end(), LineEnd::SortedYpostX);
std::sort(EndsX.begin(), EndsX.end(), LineEnd::SortedYpostX);
for (size_t j = 0; j < EndsX.size(); j++)
{
size_t edge = EndsX[j].index;
if (edge == 0) continue;
if (LineEnds[edge - 1].back_count++ == 0)
LineEnds[edge - 1].back_index1 = (j + 1);
else LineEnds[edge - 1].back_index2 = (j + 1);
}
//PARSING SORT
size_t sx = EndsX.size();
//size_t sy = EndsY.size();
size_t sxy = LineEnds.size();
for (size_t j = 0; j < LineEnds.size(); j++)
{
size_t ind1 = LineEnds[j].back_index1;
if (ind1 == 0)
Message("ERROR ind1 == 0");
double x1 = EndsX[ind1 - 1].x;
double y1 = EndsX[ind1 - 1].y;
size_t edge = EndsX[ind1 - 1].index;
//double x2 = sy? EndsY[j].x : 0;
//double y2 = sy? EndsY[j].y : 0;
//size_t ind2 = sy? EndsY[j].index : 0;
reference curve = locCurvesPool[ii0].Curves[j].curve;
curve = curve;
}
// detecting nodes among vertices
/* struct Node {
double x; double y;
size_t edge_index; // (ordered from 1; 0 means UNDEFINED)
size_t node_index; // aux field denotes Index of vertex (ordered from 1; 0 means UNDEFINED)
size_t link_index; // aux field used later to detect components (ordered from 1; 0 means UNDEFINED)
Node(double ux, double uy, size_t uindex) : x(ux), y(uy), edge_index(uindex), node_index(0), link_index(0) {}
Node(double ux, double uy, size_t uindex, size_t uNindex, size_t uLindex) : x(ux), y(uy), edge_index(uindex), node_index(uNindex), link_index(uLindex) {}
};
struct NodeLinks {
Node thisNode;
size_t edge_count; // aux count
size_t parent_index; // aux index (ordered from 1; 0 means UNDEFINED)
size_t inner_edge_index; // aux index (ordered from 1; 0 means UNDEFINED)
std::vector<Node> Nodes;
NodeLinks(Node& uNode) : thisNode(uNode.x, uNode.y, uNode.edge_index, uNode.node_index, uNode.link_index),
edge_count(0), parent_index(0), inner_edge_index(0) {}
};*/
std::vector<NodeLinks> locNodesPool;
//Message("test input EndsX");
// checking & proceeding all single-loops
for (size_t j = 0; j < LineEnds.size(); j++)
{
if (equal_points(LineEnds[j].x1, LineEnds[j].y1, LineEnds[j].x2, LineEnds[j].y2, m_precision * m_MmToUnits)) {
size_t ind1 = LineEnds[j].back_index1 - 1,
ind2 = LineEnds[j].back_index2 - 1;
EndsX[ind1].single_loop = EndsX[ind2].single_loop = 1;
locNodesPool.push_back(Node(EndsX[ind1].x, EndsX[ind1].y, EndsX[ind1].index)); //, last_node, 0));
std::vector<Node>& Nodes = locNodesPool.back().Nodes;
Nodes.push_back(Node(EndsX[ind2].x, EndsX[ind2].y, EndsX[ind2].index));
}
}
bool prev_loaded = false;
for (size_t j = 0, jprev = 0; j < EndsX.size(); j++)
{
if (EndsX[j].single_loop != 0) continue;
if (/*j == jprev ||*/ prev_loaded == false) {
//locNodesPool.push_back(Node(EndsX[jprev].x, EndsX[jprev].y, EndsX[jprev].index));
locNodesPool.push_back(Node(EndsX[j].x, EndsX[j].y, EndsX[j].index)); //, last_node, 0));
prev_loaded = true;
}
else if (equal_points(EndsX[j].x, EndsX[j].y, EndsX[jprev].x, EndsX[jprev].y, m_precision * m_MmToUnits) == false)
locNodesPool.push_back(Node(EndsX[j].x, EndsX[j].y, EndsX[j].index)); //, last_node, 0));
else
{
//node found
Node& lastNode = locNodesPool.back().thisNode;
if (equal_points(lastNode.x, lastNode.y, EndsX[j].x, EndsX[j].y, m_precision * m_MmToUnits) == false)
{
locNodesPool.push_back(Node(EndsX[j].x, EndsX[j].y, EndsX[j].index)); //, last_node, 0)); // MUST BE NOT
}
else
{
std::vector<Node>& Nodes = locNodesPool.back().Nodes;
Nodes.push_back(Node(EndsX[j].x, EndsX[j].y, EndsX[j].index));
}
}
jprev = j;
}
//PARSING NODES
size_t sn = locNodesPool.size();
int linesegs = 0;
for (size_t j = 0; j < locNodesPool.size(); j++)
{
Node& node = locNodesPool[j].thisNode;
double x0 = node.x;
double y0 = node.y;
size_t ind0 = node.edge_index;
std::vector<Node>& Nodes = locNodesPool[j].Nodes;
size_t snodes = Nodes.size();
if (snodes == 0) linesegs ++;
for (size_t jj = 0; jj < Nodes.size(); jj++)
{
double x1 = Nodes[jj].x;
double y1 = Nodes[jj].y;
size_t ind1 = Nodes[jj].edge_index;
ind1 = ind1;
}
}
// detecting components in the graph
std::vector <size_t> link_map;
std::map <size_t, size_t> comp_map;
std::map <size_t, size_t> :: iterator map_Iter;
typedef std::pair <size_t, size_t> KeyValPair;
for (size_t j = 0; j < locNodesPool.size(); j++)
{
Node& node = locNodesPool[j].thisNode;
node.node_index = (j + 1); // (ordered from 1!)
size_t ind0 = node.edge_index - 1; // (ordered from 1!)
size_t comp_index = node.node_index;
if (LineEnds[ind0].link_index == 0)
LineEnds[ind0].link_index = comp_index;
else
comp_index = LineEnds[ind0].link_index;
if (node.link_index == 0) node.link_index = comp_index;
if (comp_map.count(comp_index) == 0)
{
bool need_insert = true;
if (node.node_index != comp_index && comp_index <= link_map.size()) // special case!
{
size_t index = link_map[ comp_index - 1 ],
prev_index = 0;
while ( comp_map.find(index) == comp_map.end() && index != prev_index )
{
prev_index = index;
index = link_map[index - 1];
}
map_Iter = comp_map.find(index);
if (map_Iter != comp_map.end() && prev_index != 0)
{
map_Iter->second = node.node_index;
comp_index = node.link_index = index;
need_insert = false;
}
}
if (need_insert) comp_map.insert(KeyValPair(node.link_index, node.node_index));
}
//else { map_Iter = comp_map.find(node.link_index); }
std::vector<Node>& Nodes = locNodesPool[j].Nodes;
for (size_t jj = 0; jj < Nodes.size(); jj++)
{
size_t ind1 = Nodes[jj].edge_index - 1; // (ordered from 1!)
if (LineEnds[ind1].link_index == 0)
LineEnds[ind1].link_index = comp_index;
else
if (LineEnds[ind1].link_index != comp_index)
{ // merging bushes with different comp_index by help of the map
size_t comp_index1 = LineEnds[ind1].link_index;
size_t comp_index0 = std::min(comp_index, comp_index1);
map_Iter = comp_map.find(comp_index);
if (map_Iter != comp_map.end() && comp_index != comp_index0) comp_map.erase(comp_index);
map_Iter = comp_map.find(comp_index1);
if (map_Iter != comp_map.end() && comp_index1 != comp_index0) comp_map.erase(comp_index1);
map_Iter = comp_map.find(comp_index0);
bool need_insert = true;
if (map_Iter == comp_map.end())
{
if (node.node_index != comp_index0 && comp_index0 <= link_map.size()) // special case!
{
size_t index = link_map[ comp_index0 - 1 ],
prev_index = 0;
while ( comp_map.find(index) == comp_map.end() && index != prev_index )
{
prev_index = index;
index = link_map[index - 1];
}
map_Iter = comp_map.find(index);
if (map_Iter != comp_map.end())
{
comp_index0 = node.link_index = index;
need_insert = false;
}
}
}
if (link_map.size() >= comp_index) {
size_t next_link = link_map[comp_index - 1];
link_map[comp_index - 1] = node.node_index;
if (link_map.size() >= next_link) link_map[next_link - 1] = node.node_index;
}
if (link_map.size() >= comp_index1) {
size_t next_link = link_map[comp_index1 - 1];
link_map[comp_index1 - 1] = node.node_index;
if (link_map.size() >= next_link) link_map[next_link - 1] = node.node_index;
}
if (need_insert) comp_map.insert(KeyValPair(comp_index0, node.node_index));
else
map_Iter->second = node.node_index;
node.link_index = comp_index = comp_index0;
LineEnds[ind1].link_index = comp_index;
LineEnds[ind0].link_index = comp_index;
}
}
if (link_map.size() < node.node_index) link_map.push_back(node.link_index); // same as comp_index here
else link_map[node.node_index - 1] = node.link_index;
}
// writing components' indices to Nodes
for (size_t j = 0; j < locNodesPool.size(); j++)
{
Node& node = locNodesPool[j].thisNode;
size_t index = node.link_index,
prev_index = 0;
//if (index != link_map[ j ])
//Message("MAY BE DIFFERENT HERE!");
index = link_map[ j ];
while ( comp_map.find(index) == comp_map.end() && index != prev_index )
{
prev_index = index;
index = link_map[index - 1];
}
if (comp_map.find(index) != comp_map.end() && prev_index != 0)
{
size_t new_index = index;
index = node.link_index;
prev_index = 0;
while (comp_map.find(index) == comp_map.end() && index != prev_index )
{
prev_index = index;
size_t tmp_index = link_map[index - 1];
link_map[index - 1] = new_index;
index = tmp_index;
}
link_map[ j ] = node.link_index = new_index;
}
}
for (size_t j = 0; j < locNodesPool.size(); j++)
{
Node& node = locNodesPool[j].thisNode;
size_t new_index = link_map[ j ];
if (node.link_index != new_index) node.link_index = new_index;
//std::vector<Edge>& LineEnds = locCurvesPool[i].Curves;
if (node.edge_index != 0)
{
size_t index = node.edge_index - 1;
if (LineEnds[index].link_index != new_index) LineEnds[index].link_index = new_index;
}
}
//** Here -
//** EDGES = LineEnds.size();
//** VERTICES = locNodesPool.size();
//** COMPONENTS = comp_map.size();
//** Contours = (EDGES + COMPONENTS - VERTICES);
#if defined(DO_DEBUG)
//MESSAGE(L"TEST")
#endif
// separating from the mesh the different branches and contours to prepare the drawing
for (size_t j = 0; j < locNodesPool.size(); j++)
{
Node& node = locNodesPool[j].thisNode;
//std::vector<Edge>& LineEnds = locCurvesPool[i].Curves;
if (node.edge_index != 0)
{
size_t index = node.edge_index - 1;
if (LineEnds[index].node_index1 == 0) LineEnds[index].node_index1 = node.node_index;
else
if (LineEnds[index].node_index2 == 0) LineEnds[index].node_index2 = node.node_index;
//else Message("ERROR");
}
std::vector<Node>& Nodes = locNodesPool[j].Nodes;
for (size_t jj = 0; jj < Nodes.size(); jj++)
{
if (Nodes[jj].edge_index != 0)
{
size_t index = Nodes[jj].edge_index - 1;
if (LineEnds[index].node_index1 == 0) LineEnds[index].node_index1 = node.node_index;
else
if (LineEnds[index].node_index2 == 0) LineEnds[index].node_index2 = node.node_index;
//else Message("ERROR");
}
}
locNodesPool[j].edge_count = 1 + locNodesPool[j].Nodes.size();
locNodesPool[j].parent_index = (1 + j); // (ordered from 1!)
}
//MESSAGE(L"TEST")
//PARSE!
for (size_t j = 0; j < LineEnds.size(); j++)
{
if (LineEnds[j].node_index1 == 0 || LineEnds[j].node_index2 == 0)
{
size_t ni1 = LineEnds[j].node_index1;
size_t ni2 = LineEnds[j].node_index2;
MESSAGE(L"ERROR edge %d:\n\n ni1 = %d; ni2 = %d" MESSAGE_COMMA j+1 MESSAGE_COMMA ni1 MESSAGE_COMMA ni2)
}
if (LineEnds[j].node_index1 == LineEnds[j].node_index2)
{
size_t ni1 = LineEnds[j].node_index1;
size_t ni2 = LineEnds[j].node_index2;
//MESSAGE(L"WARN (suspicion NOT A LINESEG?) edge %d:\n\n ni1 = %d; ni2 = %d" MESSAGE_COMMA j+1 MESSAGE_COMMA ni1 MESSAGE_COMMA ni2)
}
}
/* for (size_t j = 0; j < locNodesPool.size(); j++)
if (locNodesPool[j].thisNode.node_index == 188 || locNodesPool[j].thisNode.node_index == 208)
{
double x1 = locNodesPool[j].thisNode.x, y1 = locNodesPool[j].thisNode.y;
Point(x1, y1, 3);
}*/
typedef std::map <size_t,size_t> Branches; // indices into locNodesPool
Branches locBranchesPool,
locBranchesBegs;
std::map <size_t,size_t> locEdgesPool; // indices into LineEnds
std::map <size_t,size_t> locEdgesRegistered; // back-indices into LineEnds
// first shear the bush (take away all branches to left a pure mesh of contours
std::vector<NodeLinks> locNodesPrev(locNodesPool);
std::vector<NodeLinks> locNodesWork;
do {
size_t prev_size = locBranchesPool.size();
for (size_t j = 0; j < locNodesPrev.size(); j++)
{
Node& node = locNodesPrev[j].thisNode;
std::vector<Node>& Nodes = locNodesPrev[j].Nodes;
size_t parent_index = locNodesPrev[j].parent_index;
if (locNodesPool[parent_index - 1].edge_count > 1) locNodesWork.push_back(locNodesPrev[j]);
else // if (locNodesPrev[j].edge_count <= 1) // same as Nodes.size() == 0
{
size_t inner_edge_index = locNodesPool[parent_index - 1].inner_edge_index;
size_t node_index = node.node_index;
size_t edge_index = inner_edge_index == 0? node.edge_index : Nodes[inner_edge_index - 1].edge_index;
while (locEdgesRegistered.find(edge_index) != locEdgesRegistered.end())
{
if (inner_edge_index >= Nodes.size()) break;
inner_edge_index++;
edge_index = Nodes[inner_edge_index - 1].edge_index;
}
// if (edge_index > 0) // MUST BE
if (LineEnds[edge_index - 1].node_index1 == node_index)
node_index = LineEnds[edge_index - 1].node_index2;
else node_index = LineEnds[edge_index - 1].node_index1;
bool need_relink = false;
// if (node_index > 0) // MUST BE
if (locNodesPool[node_index - 1].edge_count > 1)
{
Node& node0 = locNodesPool[node_index - 1].thisNode;
std::vector<Node>& Nodes0 = locNodesPool[node_index - 1].Nodes;
size_t inner_edge_index = locNodesPool[node_index - 1].inner_edge_index;
size_t edge_index0 = inner_edge_index == 0? node0.edge_index : Nodes0[inner_edge_index - 1].edge_index;
if (edge_index0 == edge_index) locNodesPool[node_index - 1].inner_edge_index++;
locNodesPool[node_index - 1].edge_count--;
//edge_index = edge_index0;
}
else need_relink = true;
//if (need_relink && edge_index == 4 && i == 0)
//Message("GOTCHA need_relink!");
if (locEdgesRegistered.find(edge_index) == locEdgesRegistered.end())
{
//need_relink = need_relink && (locBranchesPool.count(node.node_index) != 0);
need_relink = need_relink && (locBranchesBegs.count(node_index) != 0);
if (need_relink == false) {
locBranchesPool.insert(KeyValPair(node.node_index, node_index));
//locBranchesPool.insert(KeyValPair(node.node_index, edge_index));
locBranchesBegs.insert(KeyValPair(node_index, node.node_index)); // aux map to seek for branch beginnings
}
}
//if (locEdgesRegistered.find(edge_index) == locEdgesRegistered.end())
if (need_relink == false)
{
locEdgesPool.insert(KeyValPair(node.node_index, edge_index));
locEdgesRegistered.insert(KeyValPair(edge_index, node.node_index));
}
//if (need_relink && i == 0)
//Message("GOTCHA need_relink!");
if (need_relink
&& locBranchesBegs.count(node.node_index) != 0 && locBranchesBegs.count(node_index) != 0
&& (locBranchesBegs.find(node.node_index)->second != node_index)
&& (locBranchesBegs.find(node_index)->second != node.node_index))
{
size_t prev_index = node_index;
size_t node_index = node.node_index;
size_t new_index = locBranchesBegs.find(node_index)->second;
// locBranchesPool.erase(node.node_index);
if (prev_index != new_index) {
locBranchesBegs.erase(node_index);
locBranchesBegs.insert(KeyValPair(node_index, prev_index));
}
if (locBranchesPool.count(prev_index) != 0) locBranchesPool.erase(prev_index);
locBranchesPool.insert(KeyValPair(prev_index, node_index));
//if (locNodesPool[node_index - 1].edge_count > 1)
size_t etmp_index = edge_index;
if (locNodesPool[node_index - 1].Nodes.size() > 0)
do {
Node& node0 = locNodesPool[node_index - 1].thisNode;
std::vector<Node>& Nodes0 = locNodesPool[node_index - 1].Nodes;
size_t& inner_edge_index = locNodesPool[node_index - 1].inner_edge_index;
size_t edge_index0 = inner_edge_index == 0? node0.edge_index : Nodes0[inner_edge_index - 1].edge_index;
if (edge_index0 == edge_index) inner_edge_index++;
if (inner_edge_index > Nodes0.size()) inner_edge_index = 0;
etmp_index = edge_index0;
} while (etmp_index == edge_index);
//size_t new_index0 = 0;
if (new_index != prev_index)
locEdgesPool.erase(prev_index);
if (locEdgesPool.count(prev_index) == 0)
locEdgesPool.insert(KeyValPair(prev_index, edge_index));
if (locEdgesRegistered.count(edge_index) != 0) locEdgesRegistered.erase(edge_index);
locEdgesRegistered.insert(KeyValPair(edge_index, prev_index));
do {
locBranchesPool.erase(new_index);
locBranchesPool.erase(node_index);
locBranchesPool.insert(KeyValPair(node_index, new_index));
if (new_index != prev_index)
locEdgesPool.erase(node_index);
if (locEdgesPool.count(node_index) == 0)
locEdgesPool.insert(KeyValPair(node_index, etmp_index));
if (locEdgesRegistered.count(etmp_index) != 0) locEdgesRegistered.erase(etmp_index);
locEdgesRegistered.insert(KeyValPair(etmp_index, node_index));
prev_index = node_index;
node_index = new_index;
if (locBranchesBegs.count(node_index) == 0)
{
locBranchesBegs.erase(new_index);
locBranchesBegs.insert(KeyValPair(node_index, prev_index));
break;
}
new_index = locBranchesBegs.find(node_index)->second;
if (locEdgesPool.count(new_index) != 0)
etmp_index = locEdgesPool.find(new_index)->second;
// locBranchesBegs.erase(new_index);
// locBranchesBegs.insert(KeyValPair(new_index, node_index));
locBranchesBegs.erase(node_index);
locBranchesBegs.insert(KeyValPair(node_index, prev_index));
}
while (1);//(locBranchesBegs.count(new_index) != 0); // && new_index0 != 0);
}
}
}
//if (locNodesWork.size() == locNodesPrev.size()) break;
if (prev_size == locBranchesPool.size()) break;
locNodesPrev.clear();
locNodesPrev.insert(locNodesPrev.begin(), locNodesWork.begin(), locNodesWork.end());
locNodesWork.clear();
} while (locNodesPrev.size() > 0);
locNodesWork.clear();
//locEdgesRegistered.clear();
for (size_t j = 0; j < locNodesPrev.size(); j++)
{
Node& node = locNodesPrev[j].thisNode;
double x = node.x, y = node.y;
/* if (m_CurrentViewIndex != 0)
{
SetViewMtr(m_CurrentViewIndex,true);
ksPointFromMtr (x, y, &x, &y);
_DeleteMtr(), _DeleteMtr();
}*/
// Point(x, y+0, 5);
}
size_t BRunches0 = locBranchesPool.size(); // all bare branches
size_t BRunches1 = locNodesPrev.size(); // all contours
//MESSAGE(L"Nodes \n\nBRunches0 = %d\nBRunches1 = %d" MESSAGE_COMMA BRunches0 MESSAGE_COMMA BRunches1)
std::map <size_t,size_t> DrawnEdges; // indices into LineEnds to register all drawn edges (find the lost ones)
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
IKompasDocument2DPtr pkdDocument = 0;
doc7->QueryInterface(&pkdDocument);
IViewPtr ivpView = pkdDocument->ViewsAndLayersManager->Views->View[0];
IDrawingContainerPtr pdcContainer = 0;
ivpView->QueryInterface(&pdcContainer);
bool contour_state = false;
equi_curves.clear();
// second we draw the bush branches left after shearing
while (locBranchesPool.size() > 0)
{
IDrawingContoursPtr idcContours = pdcContainer->DrawingContours;
IDrawingObjectPtr idoObject = 0;
IDrawingContourPtr idcContour = 0;
IContourPtr pContour = 0;
map_Iter = locBranchesPool.begin();
size_t index = map_Iter->first;
size_t index0 = index;
while (locBranchesBegs.find(index) != locBranchesBegs.end())
{
index = locBranchesBegs.find(index)->second;
if (locBranchesPool.count(index) != 0)
if (index0 != index) continue;
else break;
std::map <size_t, size_t> :: iterator test_Iter = map_Iter;
if (++test_Iter == locBranchesPool.end())
{
break; // BE NEVER but may occur once per each component!
}
else map_Iter = test_Iter;
index = map_Iter->first;
index0 = index;
}
if (locBranchesPool.count(index) == 0) break; // still may occur ?! NEVER now
map_Iter = locBranchesPool.find(index);
index = map_Iter->second;
size_t tmp_index = map_Iter->first;
size_t etmp_index = 0;
if (locEdgesPool.count(map_Iter->first) > 0)
etmp_index = locEdgesPool.find(map_Iter->first)->second;
if (etmp_index != 0)
index = (LineEnds[etmp_index - 1].node_index1 == tmp_index)? LineEnds[etmp_index - 1].node_index2 : LineEnds[etmp_index - 1].node_index1;
//? index = (LineEnds[index - 1].node_index1 == tmp_index)? LineEnds[index - 1].node_index2 : LineEnds[index - 1].node_index1;
double x1 = locNodesPool[map_Iter->first - 1].thisNode.x;
double y1 = locNodesPool[map_Iter->first - 1].thisNode.y;
double x2 = locNodesPool[index - 1].thisNode.x; // locNodesPool[map_Iter->second - 1].thisNode.x;
double y2 = locNodesPool[index - 1].thisNode.y; // locNodesPool[map_Iter->second - 1].thisNode.y;
reference curve = (etmp_index == 0)? 0 : LineEnds[etmp_index - 1].curve;
// setting color for page
{
unsigned short style = locCurvesPool[ii0].style;
unsigned long color = locCurvesPool[ii0].color;
double width = locCurvesPool[ii0].width;
/* SetCurrentColor(color);
double widthTuning = (m_CurrentViewScale > 0.5)? 0.5 / m_CurrentViewScale : 1.0; // this isn't nessessary but makes drawins more fine and readable!
widthTuning = 1.0; // better for stamps etc. / views be with widthTuning != 1?
if (PseudoGroupMode == true &&
(m_SaveViewMatricesPdfMode == 0 || m_GenObject != 0) && m_CurrentViewIndex != 0)
SetCurrentLineWidth(width * m_CurrentViewScale * widthTuning);
else
SetCurrentLineWidth(width * widthTuning);*/
}
bool needStroke = false;
while (etmp_index != 0) //while (1) // while (map_Iter != locBranchesPool.end())
{
//PseudoGroupMode = false;
/* if (PseudoGroupMode == false)
if (needStroke == false) m_pPainter->MoveTo(x1, y1);*/
//int bbb = ExistGroupObj(rGroup);
if ( DrawnEdges.count(etmp_index) == 0 ) //? doesn't work
{
bool accepted = true;
if (PseudoGroupMode == false)
{
m_issingle = (contour_state == false);
if (contour_state == false)
{
//Message("0");
contour_state = true;
m_BegPoint.x = x1, m_BegPoint.y = y1;
m_swapped = CheckSwapCurve(curve);
equi_curves.clear();
equi_curves_count = 0;
}
if (m_ProcessClosedOnly == 0 && count_mode == false)
{
reference obj = 0;
m_aux_scratch = 0;
//Message("0 - branch");
obj = Draw2DElement(curve);
if (m_issingle && m_aux_scratch == 0)
idoObject = ksTransferReference(obj, 0);
else if (obj) {
m_issingle = false;
if (idcContour == 0) {
//Contour(1);
//m_pKompasDoc5->ksContour(1);
idcContour = idcContours->Add();
idcContour->QueryInterface(&pContour);
}
if (idoObject) {
pContour->CopyCurve(idoObject, FALSE);
idoObject->Delete(); idoObject = 0;
}
IDrawingObjectPtr pCurve = 0;
if (m_aux_scratch) {
pCurve = ksTransferReference(m_aux_scratch, 0);
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
m_aux_scratch = 0;
}
pCurve = obj? ksTransferReference(obj, 0) : 0;
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
if (obj) DeleteObj(obj);
}
equi_curves.push_back(curve);
equi_curves_count++;
}
}
else if (etmp_index > 0)
{
/* m_PseudoGroup.push_back(LineEnds[etmp_index - 1].curve);
m_PseudoGroupStartPoints.push_back(std::pair<double,double>(x1,y1));*/
}
needStroke = needStroke || accepted;
/*? doesn't work
DrawnEdges.insert(KeyValPair(etmp_index,map_Iter->first));
locEdgesRegistered.erase(etmp_index);
}*/
}
else if (needStroke) {
needStroke = false;
if (PseudoGroupMode == false) { // m_pPainter->Stroke();
if (contour_state == true)
{
contour_state = false;
if (m_ProcessClosedOnly == 0)
{
if (contours_count++, count_mode == false)
{
//reference contour = EndObj();
//reference contour = m_pKompasDoc5->ksEndObj();
if (pContour) {
int pcount = pContour->Count;
if (pContour->Count > 0)
{
idcContour->Update();
PumpWaitingMessages();
}
}
#if defined(DO_DEBUG)
//Message("1");
#endif
reference contour = idoObject? idoObject->Reference : idcContour->Reference;
//equi_contours.push_back(equi_contour(contour, issingle, m_swapped, equi_curves));
if (!count_mode) equiparam->geoObj = contour;
if (TestInterrupt("Прервать операцию?", contours_count)) return contours_count;
/*if (Equidistant(equiparam) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");*/
EquidistantParam loc_equiparam = *equiparam;
//if (DrawEquidistant(&loc_equiparam, m_swapped) == 0) //параметры эквидистанты
if (m_issingle == false) idoObject = idcContour;
if (DrawEquidistant7(idoObject, &loc_equiparam, m_swapped) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");
if (equi_curves.size() == 0) ProcessMarks(contour, 0, &loc_equiparam);
else
for (int i = 0; i < equi_curves.size(); i++)
ProcessMarks(equi_curves[i], contour, &loc_equiparam);
equi_curves.clear();
//if (contour) DeleteObj(contour);
if (idcContour) idcContour->Delete();
if (idoObject) idoObject->Delete();
}
}
}
} else {
/* DrawProtoContour2(false);
m_PseudoGroup.clear();
m_PseudoGroupStartPoints.clear();*/
}
}
std::map <size_t, size_t> :: iterator imap = locEdgesPool.find(map_Iter->first);
if (needStroke && imap != locEdgesPool.end()) {
DrawnEdges.insert(KeyValPair(imap->second,imap->first));
locEdgesRegistered.erase(imap->second);
}
locBranchesBegs.erase(map_Iter->first);
locBranchesPool.erase(map_Iter->first);
map_Iter = locBranchesPool.find(index);
if (map_Iter == locBranchesPool.end()) break;
index = map_Iter->second;
size_t tmp_index = map_Iter->first;
/*size_t*/ etmp_index = 0; //! BUG in C++ (while(etmp_index) ABOVE is misunderstood with this declaration)
if (locEdgesPool.count(map_Iter->first) > 0)
etmp_index = locEdgesPool.find(map_Iter->first)->second;
if (etmp_index != 0)
index = (LineEnds[etmp_index - 1].node_index1 == tmp_index)? LineEnds[etmp_index - 1].node_index2 : LineEnds[etmp_index - 1].node_index1;
//? index = (LineEnds[index - 1].node_index1 == tmp_index)? LineEnds[index - 1].node_index2 : LineEnds[index - 1].node_index1;
x1 = locNodesPool[map_Iter->first - 1].thisNode.x;
y1 = locNodesPool[map_Iter->first - 1].thisNode.y;
x2 = locNodesPool[index - 1].thisNode.x;
y2 = locNodesPool[index - 1].thisNode.y;
curve = (etmp_index == 0)? 0 : LineEnds[etmp_index - 1].curve;
}
if (needStroke)
if (PseudoGroupMode == false) { // m_pPainter->Stroke();
if (contour_state == true)
{
contour_state = false;
if (m_ProcessClosedOnly == 0)
{
if (contours_count++, count_mode == false)
{
//reference contour = EndObj();
//reference contour = m_pKompasDoc5->ksEndObj();
if (pContour) {
int pcount = pContour->Count;
if (pContour->Count > 0)
{
idcContour->Update();
PumpWaitingMessages();
}
}
#if defined(DO_DEBUG)
//Message("2");
#endif
reference contour = idoObject? idoObject->Reference : idcContour->Reference;
//equi_contours.push_back(equi_contour(contour, issingle, m_swapped, equi_curves));
if (!count_mode) equiparam->geoObj = contour;
if (TestInterrupt("Прервать операцию?", contours_count)) return contours_count;
/*if (Equidistant(equiparam) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");*/
EquidistantParam loc_equiparam = *equiparam;
//if (DrawEquidistant(&loc_equiparam, m_swapped) == 0) //параметры эквидистанты
if (m_issingle == false) idoObject = idcContour;
if (DrawEquidistant7(idoObject, &loc_equiparam, m_swapped) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");
if (equi_curves.size() == 0) ProcessMarks(contour, 0, &loc_equiparam);
else
for (int i = 0; i < equi_curves.size(); i++)
ProcessMarks(equi_curves[i], contour, &loc_equiparam);
equi_curves.clear();
//if (contour) DeleteObj(contour);
if (idcContour) idcContour->Delete();
if (idoObject) idoObject->Delete();
}
/* RefreshKompasActiveDocument();
ksExecuteKompasCommand(ksCMRefresh, 1);
kompasAPI->ksPumpWaitingMessages();*/
}
}
} else {
/* DrawProtoContour2(false);
m_PseudoGroup.clear();
m_PseudoGroupStartPoints.clear();*/
}
}
typedef std::map <size_t,size_t> Contours; // indices into locNodesPool
Contours locContoursPool,
locContoursEdges,
locContoursPassed;
locEdgesRegistered.clear();
// finally draw the contours by pulling together all closed paths
for (size_t j = 0; j < locNodesPrev.size(); j++)
{
NodeLinks& node_elem = locNodesPool[locNodesPrev[j].parent_index - 1];
locContoursPool.insert(KeyValPair(locNodesPrev[j].thisNode.node_index, locNodesPrev[j].parent_index));
locContoursEdges.insert(KeyValPair(locNodesPrev[j].thisNode.node_index, 0));
node_elem.inner_edge_index = 0;
node_elem.edge_count = 1 + node_elem.Nodes.size(); // = locNodesPrev[j].edge_count;
}
std::vector <size_t> edge_map;
//MESSAGE(L"DRAW CONT")
while (locContoursPool.size() > 0)
{
IDrawingContoursPtr idcContours = pdcContainer->DrawingContours;
//IDrawingObjectPtr idoObject = 0;
IDrawingContourPtr idcContour = 0;
IContourPtr pContour = 0;
bool need_break = false;
map_Iter = locContoursPool.begin();
locContoursPassed.clear();
locContoursPassed.insert(KeyValPair(map_Iter->first, 0));
//bool issingle = false;
m_issingle = false;
reference singleton = 0;
double beg_x1, beg_y1, beg_x2, beg_y2;
size_t node_index0 = map_Iter->first;
size_t parent_index = map_Iter->second;
size_t node_index = node_index0,
prev_index = node_index0;
do {
map_Iter = locContoursPool.find(node_index);
if (need_break || map_Iter == locContoursPool.end()) {need_break = true; break;} // ?NEVER
parent_index = map_Iter->second;
Node& node = locNodesPool[parent_index - 1].thisNode;
std::vector<Node>& Nodes = locNodesPool[parent_index - 1].Nodes;
size_t& inner_edge_index = locNodesPool[parent_index - 1].inner_edge_index;
size_t last_index = prev_index;
size_t edge_index = 0;
//bool need_break = false;
do {
last_index = prev_index;
prev_index = node_index = node.node_index; // == node_index0
do {
if (inner_edge_index > Nodes.size()) {need_break = true; break;}
edge_index = (inner_edge_index == 0)? node.edge_index : Nodes[inner_edge_index - 1].edge_index;
inner_edge_index++;
} while (DrawnEdges.count(edge_index) != 0);
if (need_break) break;
// if (edge_index > 0) // MUST BE
if (LineEnds[edge_index - 1].node_index1 == node_index)
node_index = LineEnds[edge_index - 1].node_index2;
else node_index = LineEnds[edge_index - 1].node_index1;
} while (inner_edge_index <= Nodes.size() &&
( (node_index != node_index0 && locContoursPool.find(node_index) == locContoursPool.end())
|| ( last_index == node_index && locEdgesRegistered.count(edge_index) != 0 ) ));
//|| (last_index == node_index && (locContoursEdges.count(prev_index) != 0 && locContoursEdges.find(prev_index)->second != 0)) ));
if (need_break) break; // no cycle found
if (locContoursEdges.count(prev_index) != 0)
locContoursEdges.find(prev_index)->second = edge_index;
locEdgesRegistered.insert(KeyValPair(edge_index, 0));
if (locContoursPassed.find(node_index) == locContoursPassed.end())
{
if (locContoursPassed.count(prev_index) != 0)
locContoursPassed.find(prev_index)->second = node_index;
locContoursPassed.insert(KeyValPair(node_index, 0));
continue;
}
m_issingle = locContoursPassed.size() == 1;
singleton = 0;
map_Iter = locContoursPassed.find(node_index);
prev_index = node_index0 = map_Iter->first;
node_index = map_Iter->second;
while (locContoursPassed.size() > 0 && map_Iter != locContoursPassed.end()) // && node_index != 0)
{
prev_index = map_Iter->first;
node_index = map_Iter->second;
double x1 = locNodesPool[prev_index - 1].thisNode.x;
double y1 = locNodesPool[prev_index - 1].thisNode.y;
double x2 = locNodesPool[(node_index == 0? node_index0 : node_index) - 1].thisNode.x;
double y2 = locNodesPool[(node_index == 0? node_index0 : node_index) - 1].thisNode.y;
if (m_issingle && prev_index == node_index0)
x2 = locNodesPool[prev_index - 1].Nodes[0].x,
y2 = locNodesPool[prev_index - 1].Nodes[0].y;
map_Iter = locContoursPassed.find(node_index);
if (prev_index == node_index0)
{
// setting color for page
{
unsigned short style = locCurvesPool[ii0].style;
unsigned long color = locCurvesPool[ii0].color;
double width = locCurvesPool[ii0].width;
/* SetCurrentColor(color);
double widthTuning = (m_CurrentViewScale > 0.5)? 0.5 / m_CurrentViewScale : 1.0; // this isn't nessessary but makes drawins more fine and readable!
widthTuning = 1.0; // better for stamps etc. / views be with widthTuning != 1?
if (PseudoGroupMode == true &&
(m_SaveViewMatricesPdfMode == 0 || m_GenObject != 0) && m_CurrentViewIndex != 0)
SetCurrentLineWidth(width * m_CurrentViewScale * widthTuning);
else
SetCurrentLineWidth(width * widthTuning);*/
}
/* if (PseudoGroupMode == false)
m_pPainter->MoveTo(x1, y1);*/
}
if (locContoursEdges.count(prev_index) != 0)
edge_index = locContoursEdges.find(prev_index)->second;
reference curve = (edge_index == 0)? 0 : LineEnds[edge_index - 1].curve;
//if ( DrawnEdges.count(etmp_index) == 0 ) //? doesn't work
if (PseudoGroupMode == false)
{
if (contour_state == false)
{
contour_state = true;
m_BegPoint.x = x1, m_BegPoint.y = y1;
beg_x1 = x1, beg_y1 = y1;
beg_x2 = x2, beg_y2 = y2;
//Message("000000000");
m_swapped = CheckSwapCurve(curve);
equi_curves.clear();
equi_curves_count = 0;
//if (m_issingle) {
// int type = GetObjParam(curve, 0, 0, ALLPARAM);
// m_issingle = (type != CONTOUR_OBJ);
//}
//if (!issingle) Contour(1);
//if (!m_issingle) m_pKompasDoc5->ksContour(1);
}
reference obj = 0;
m_aux_scratch = 0;
if (count_mode == false)
{
//int type = GetObjParam(curve, 0, 0, ALLPARAM);
//bool iscontour = type == CONTOUR_OBJ;
if (m_issingle && m_aux_scratch == 0) singleton = curve;
else {
//Message("00000 - contour");
obj = Draw2DElement(curve, m_issingle);
if (obj) {
m_issingle = false;
if (idcContour == 0) {
//Contour(1);
//m_pKompasDoc5->ksContour(1);
idcContour = idcContours->Add();
idcContour->QueryInterface(&pContour);
}
IDrawingObjectPtr pCurve = 0;
if (m_aux_scratch) {
pCurve = ksTransferReference(m_aux_scratch, 0);
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
m_aux_scratch = 0;
}
pCurve = obj? ksTransferReference(obj, 0) : 0;
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
if (obj) DeleteObj(obj);
}
}
equi_curves.push_back(curve);
equi_curves_count++;
}
}
if (edge_index != 0) DrawnEdges.insert(KeyValPair(edge_index, prev_index));
if (PseudoGroupMode == true && edge_index > 0)
{
/* m_PseudoGroup.push_back(LineEnds[edge_index - 1].curve);
m_PseudoGroupStartPoints.push_back(std::pair<double,double>(x1,y1));*/
}
locContoursPool.erase(prev_index);
}
} while (node_index != 0 && node_index != node_index0);
if (need_break) break;
locContoursPool.erase(node_index);
if (PseudoGroupMode == false) {
if (contour_state == true)
{
//m_pPainter->ClosePath();
//m_pPainter->Stroke();
m_aux_scratch = 0;
if (count_mode == false)
{
//Message("000");
if (m_issingle && m_swapped == false) m_BegPoint.x = beg_x2, m_BegPoint.y = beg_y2;
//CheckTipWithScratch(beg_x1, beg_y1);
if (m_swapped == false)
CheckSwapBegPoint(beg_x1, beg_y1, beg_x2, beg_y2);
else
CheckSwapBegPoint(beg_x2, beg_y2, beg_x1, beg_y1);
if (m_aux_scratch) {
if (idcContour == 0) {
//Contour(1);
//m_pKompasDoc5->ksContour(1);
idcContour = idcContours->Add();
idcContour->QueryInterface(&pContour);
}
IDrawingObjectPtr pCurve = 0;
if (m_aux_scratch) {
pCurve = ksTransferReference(m_aux_scratch, 0);
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
m_aux_scratch = 0;
}
reference obj = 0;
if (m_issingle) {
m_BegPoint.x = (m_swapped == false)? beg_x1 : beg_x2; // NO MORE scratches!
m_BegPoint.y = (m_swapped == false)? beg_y1 : beg_y2;
obj = Draw2DElement(singleton); //, m_issingle);
}
if (obj) {
pCurve = obj? ksTransferReference(obj, 0) : 0;
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
if (obj) DeleteObj(obj);
m_issingle = false;
}
}
}
/*
if (equal_points(m_BegPoint.x, m_BegPoint.y, beg_x1, beg_y1, m_precision * m_MmToUnits)
&& equal_points(m_BegPoint.x, m_BegPoint.y, beg_x1, beg_y1) == false) {
reference aux_scratch = LineSeg(m_BegPoint.x, m_BegPoint.y, beg_x1, beg_y1, m_curves_style);
AddObjGroup(m_grpAuxScratches, aux_scratch);
}
*/
contour_state = false;
reference contour = 0;
//contour = (!issingle)? EndObj() : singleton;
//contour = (!m_issingle)? m_pKompasDoc5->ksEndObj() : singleton;
if (contours_count++, count_mode == false)
{
if (pContour) {
int pcount = pContour->Count;
BOOL Closed = pContour->Closed;
pContour->Closed = TRUE;
if (pContour->Count > 0)
{
idcContour->Update();
PumpWaitingMessages();
}
}
contour = m_issingle? singleton : idcContour->Reference;
}
equi_contour::pThis = this;
if (count_mode == false)
equi_contours.push_back(equi_contour(contour, m_issingle, m_swapped, equi_curves, equi_curves_count));
equi_curves.clear();
// moved for later!
//equiparam->side = CheckContourSide(contour, issingle);
//equiparam->geoObj = contour;
//Equidistant(equiparam); //параметры эквидистанты
//if (contour) DeleteObj(contour);
break; // IMPORTANT! after each contour
}
} else {
/* DrawProtoContour2(true);
m_PseudoGroup.clear();
m_PseudoGroupStartPoints.clear()*/
}
/* RefreshKompasActiveDocument();
ksExecuteKompasCommand(ksCMRefresh, 1);
kompasAPI->ksPumpWaitingMessages();*/
}
size_t EDGES = LineEnds.size();
size_t VERTICES = locNodesPool.size();
size_t COMPONENTS = comp_map.size();
size_t CONTOURS = EDGES + COMPONENTS - VERTICES;
if (count_mode) {
//contours_count += CONTOURS; - may be counted as so too (but no interactivity in dialog)
//break; // no need in ii-cycle
}
if(0)
MESSAGE(L"Map (line type %d, subcycle = %d) \n\nEDGES = %d\nVERTICES = %d\nCOMPONENTS = %d\n\nContours = %d" \
MESSAGE_COMMA ii0 MESSAGE_COMMA ii MESSAGE_COMMA EDGES MESSAGE_COMMA VERTICES MESSAGE_COMMA COMPONENTS MESSAGE_COMMA CONTOURS)
//if (ii == 0)
{
size_t LineEndsSize = LineEnds.size();
for (size_t j = LineEndsSize; j > 0; j--)
{
size_t index = j - 1;
size_t node1 = LineEnds[index].node_index1;
size_t node2 = LineEnds[index].node_index2;
map_Iter = DrawnEdges.find(index + 1); // (ordered from 1!)
if (map_Iter != DrawnEdges.end() && (map_Iter->second == node1 || map_Iter->second == node2))
LineEnds.erase(LineEnds.begin() + index);
}
}
#if defined(DO_DEBUG) == 0 //LICENCING!
if (count_mode == false && contours_count >= 10) { contours_left = false; continue; break; }
#endif
contours_left = (ii == 0) || (EDGES + COMPONENTS - VERTICES > 0); // may be insufficient?
contours_left = contours_left || LineEnds.size() > 0;
}
if (0)
if (equi_contours.size() > 0) // drawing equidistants and clearing
{
#if defined(DO_DEBUG)
MESSAGE(L"equi_contours.size() = %d" MESSAGE_COMMA equi_contours.size())
#endif
//MESSAGE(L"equi_contours.size() > 0")
// WRONG!?:
//std::sort(equi_contours.begin(), equi_contours.end(), equi_contour::SortedContours);
std::sort(equi_contours.begin(), equi_contours.end(), equi_contour::SortedContours);
int enclosed_count = 0;
bool enclosed = false;
reference enclosed_contour = 0;
for (int i = (int)equi_contours.size() - 1; i >= 0; i--)
{
if (enclosed_contour)
enclosed = IsContourInsideContour(equi_contours[i].contour, enclosed_contour, this);
if (!enclosed) {
if (enclosed_contour) DeleteObj(enclosed_contour);
enclosed_contour = 0;
}
if (enclosed)
enclosed_count += 1;
else enclosed_count = 0;
reference contour = equi_contours[i].contour;
m_issingle = equi_contours[i].issingle;
bool trigger_inside = (m_ProcessEnclosedContours != 0) && (enclosed_count % 2) != 0;
bool right_ort = true;
int inside = CheckContourSide(contour, equi_contours[i].swapped_curve, m_issingle);
int side = (inside == 3)? (m_StockOutCheck != 0? 1 : 0) : // left side or both!
(inside == 1)? (m_StockOutCheck != 0? 0 : 1) : 0; // right side or both!
char buf[128];
::sprintf(buf, "inside : %d, side : %d", inside, side);
// ::Message(buf);
if (!count_mode)
{
if (equiparam->side < 2) {
equiparam->side = side;
if (trigger_inside) equiparam->side = equiparam->side == 1? 0 : 1;
if (equiparam->side == 0) {
equiparam->radLeft = std::max(0.0, ((inside == 3) == trigger_inside)? m_StockOut : m_StockIn);
equiparam->radLeft *= m_MmToUnits;
} else {
equiparam->radRight = std::max(0.0, ((inside == 3) == trigger_inside)? m_StockIn : m_StockOut);
equiparam->radRight *= m_MmToUnits;
}
} else {
if ((side == 0) == trigger_inside) {
equiparam->radRight = std::max(0.0, m_StockOut); // радиус эквидистанты справа по направлению кривой
equiparam->radLeft = std::max(0.0, m_StockIn); // радиус эквидистанты слева
} else {
equiparam->radRight = std::max(0.0, m_StockIn); // радиус эквидистанты справа по направлению кривой
equiparam->radLeft = std::max(0.0, m_StockOut); // радиус эквидистанты слева
}
equiparam->radRight *= m_MmToUnits;
equiparam->radLeft *= m_MmToUnits;
}
equiparam->geoObj = contour;
}
equi_curves.clear();
if (contours_count++, count_mode == false)
{
equi_curves.insert(equi_curves.begin(),equi_contours[i].equi_curves.begin(),equi_contours[i].equi_curves.end());
equi_contours[i].equi_curves.clear();
if (TestInterrupt("Прервать операцию?", contours_count)) return contours_count;
/*if (Equidistant(equiparam) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");*/
equi_curves_count = equi_contours[i].equi_curves_count;
if (DrawEquidistant(equiparam, equi_contours[i].swapped_curve) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");
for (int ic = 0; ic < (int)equi_curves.size(); ic++) {
if (ic == 0 && m_CurveParts.count(equi_curves[0]) > 0) {
ProcessMarks(m_CurveParts.find( equi_curves[0] )->second, equi_contours[i].contour, equiparam);
break;
}
ProcessMarks(equi_curves[ic], equi_contours[i].contour, equiparam);
}
equi_curves.clear();
}
// char buf[128];
// ::sprintf(buf, "контур : %d", i);
// ::Message(buf);
if (!enclosed_contour) enclosed_contour = equi_contours[i].contour;
if (contour && enclosed_contour != contour) DeleteObj(contour);
//if (enclosed)
// enclosed_count += 1;
//else enclosed_count = 0;
}
if (enclosed_contour) DeleteObj(enclosed_contour);
equi_contours.clear();
}
if (1) // SLOW ENCLOSING VERSION!!
if (equi_contours.size() > 0) // drawing equidistants and clearing
{
#if defined(DO_DEBUG)
MESSAGE(L"SLOW equi_contours.size() > 0 \n equi_contours.size() = %d" MESSAGE_COMMA equi_contours.size())
#endif
// WRONG!?:
//std::sort(equi_contours.begin(), equi_contours.end(), equi_contour::SortedContours);
for (int i = 0; i < (int)equi_contours.size(); i++)
for (int j = 0; j < i; j++)
{
bool enclosed = IsContourInsideContour(equi_contours[j].contour, equi_contours[i].contour, this);
if (enclosed) equi_contours[j].enclose_count++;
else if (IsContourInsideContour(equi_contours[i].contour, equi_contours[j].contour, this))
equi_contours[i].enclose_count++;
}
//std::sort(equi_contours.begin(), equi_contours.end(), equi_contour::SortedContours);
if (count_mode) contours_count += equi_contours.size();
else
#if defined(DO_DEBUG) //LICENCING!
for (int i = (int)equi_contours.size() - 1; i >= 0; i--)
#else //LICENCING!
for (int i = std::min((int)(equi_contours.size() - 1), 10 - 1); i >= 0; i--)
#endif
{
int enclosed_count = equi_contours[i].enclose_count;
reference contour = equi_contours[i].contour;
m_issingle = equi_contours[i].issingle;
bool trigger_inside = (m_ProcessEnclosedContours != 0) && (enclosed_count % 2) != 0;
bool right_ort = true;
EquidistantParam loc_equiparam = *equiparam;
#if defined(DO_DEBUG)
//::Message("Prepare equiparam");
#endif
int inside = CheckContourSide(contour, equi_contours[i].swapped_curve, m_issingle);
#if defined(DO_DEBUG)
//if (inside == 1)::Message("Prepare equiparam = inside == 1!");
//if (inside == 3)::Message("Prepare equiparam = inside == 3!");
//if (inside == 2)::Message("Prepare equiparam = inside == 2!");
//if (inside == 0)::Message("Prepare equiparam = inside == 0!");
#endif
int side = (inside == 1)? (m_StockOutCheck != 0? 1 : 0) : // left side or both!
(inside == 3)? (m_StockOutCheck != 0? 0 : 1) : 0; // right side or both!
if (loc_equiparam.side < 2) {
loc_equiparam.side = side;
if (trigger_inside) loc_equiparam.side = loc_equiparam.side == 1? 0 : 1;
if (loc_equiparam.side == 0) {
loc_equiparam.radLeft = std::max(0.0, ((inside == 1) == trigger_inside)? m_StockOut : m_StockIn);
loc_equiparam.radLeft *= m_MmToUnits;
} else {
loc_equiparam.radRight = std::max(0.0, ((inside == 1) == trigger_inside)? m_StockIn : m_StockOut);
loc_equiparam.radRight *= m_MmToUnits;
}
} else {
if ((side == 0) == trigger_inside) {
loc_equiparam.radRight = std::max(0.0, m_StockOut); // радиус эквидистанты справа по направлению кривой
loc_equiparam.radLeft = std::max(0.0, m_StockIn); // радиус эквидистанты слева
} else {
loc_equiparam.radRight = std::max(0.0, m_StockIn); // радиус эквидистанты справа по направлению кривой
loc_equiparam.radLeft = std::max(0.0, m_StockOut); // радиус эквидистанты слева
}
loc_equiparam.radRight *= m_MmToUnits;
loc_equiparam.radLeft *= m_MmToUnits;
}
loc_equiparam.geoObj = contour;
if (TestInterrupt("Прервать операцию?", contours_count)) return contours_count;
if (equi_contours[i].swapped_curve) {
#if defined(DO_DEBUG)
//::Message("Prepare equiparam = SWAPPED!");
#endif
if (loc_equiparam.side != 2) loc_equiparam.side = loc_equiparam.side == 0? 1 : 0;
double tmp = loc_equiparam.radLeft;
loc_equiparam.radLeft = loc_equiparam.radRight;
loc_equiparam.radRight = tmp;
}
equi_curves.clear();
equi_curves.insert(equi_curves.begin(),equi_contours[i].equi_curves.begin(),equi_contours[i].equi_curves.end());
equi_contours[i].equi_curves.clear();
/*if (Equidistant(&loc_equiparam) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");*/
equi_curves_count = equi_contours[i].equi_curves_count;
IDrawingContourPtr idcContour = 0;
IDrawingObjectPtr idoObject = 0;
if (m_issingle) idoObject = ksTransferReference(contour, 0);
else idcContour = ksTransferReference(contour, 0);
if (m_issingle == false) idoObject = idcContour;
if (DrawEquidistant7(idoObject, &loc_equiparam, equi_contours[i].swapped_curve) == 0) //параметры эквидистанты
Message("Error drawing Equidistant");
for (int ic = 0; ic < (int)equi_curves.size(); ic++) {
if (ic == 0 && m_CurveParts.count(equi_curves[0]) > 0) {
ProcessMarks(m_CurveParts.find( equi_curves[0] )->second, equi_contours[i].contour, &loc_equiparam);
break;
}
ProcessMarks(equi_curves[ic], equi_contours[i].contour, &loc_equiparam);
}
equi_curves.clear();
// char buf[128];
// ::sprintf(buf, "контур : %d", i);
// ::Message(buf);
//if (contour) DeleteObj(contour);
if (idcContour) idcContour->Delete();
//if (idoObject) idoObject->Delete(); // NEVER!
}
equi_contours.clear();
}
if (m_grpAuxScratches && ExistGroupObj(m_grpAuxScratches))
DeleteObj(m_grpAuxScratches);
m_grpAuxScratches = 0;
}
// if (rGroup) DeleteObj(rGroup);
// if (rGroup) DeleteObj(rGroup);
return contours_count;
}
void CSewingDlg::ProcessMarks(reference curve, reference contour, EquidistantParam* equiparam)
{
if (m_MarkingCheck == 0 || !curve || !equiparam || m_MaxMarksNum < 1) return;
#if defined(DO_DEBUG)
//Message("ProcessMarks");
#endif
if (contour == 0) contour = curve;
const double perimeter = ksGetCurvePerimeter (curve, ST_MIX_MM);
bool closed = ksIsCurveClosed (curve) == 1;
// if (perimeter < m_MaxMarksNum * m_MarkingStep) return;
if (perimeter < m_MarkingStep) return;
int type = GetObjParam(curve, 0, 0, ALLPARAM);
double t1, t2, x1, y1, x2, y2;
ksGetCurveMinMaxParametr (curve, &t1, &t2);
ksGetCurvePoint(curve, t1, &x1, &y1);
ksGetCurvePoint(curve, t2, &x2, &y2);
ksGetCurvePoint(curve, t1*0.8+t2*0.2, &x1, &y1);
Point (x1, y1, 5);
reference pointArr = ksPointsOnCurve (curve, m_MaxMarksNum + (closed? 0 : 1+1));
if (!pointArr) return;
for (int i = (closed? 0 : 1); i < m_MaxMarksNum + (closed? 0 : 1); i++)
{
//double t = t1 + i * ((t2 - t1) / m_MaxMarksNum); // doesn't give equal steps!
MathPointParam par;
if (GetArrayItem (pointArr, i, &par, sizeof (MathPointParam)))
{
double kx = par.x, ky = par.y, norm;
//ksGetCurvePoint(curve, t, &kx, &ky);
double kx0 = kx, ky0 = ky;
norm = ksGetCurvePerpendicular(curve, kx, ky);
int type = GetObjParam(curve, 0, 0, ALLPARAM);
double nx = kx0, ny = ky0;
MovePoint(&nx, &ny, norm, 0.1);
double tx = kx0, ty = ky0;
ksGetCurvePointProjection(contour, tx, ty, &tx, &ty);
double tx0 = tx, ty0 = ty;
bool right_ort = true;
int dir = 1;
if (ksMovePointOnCurve (contour, &tx, &ty, 0.01, dir))
{
right_ort = 0 <= ( (tx - tx0) * (ny - ky0) - (nx - kx0) * (ty - ty0) );
}
if (equiparam->side%2 == 0) { // 0 or 2
MovePoint(&kx, &ky, norm + (right_ort? 0 : 180), equiparam->radLeft);
LineSeg(kx0, ky0, kx, ky, EQUI_STYLE);
}
if (equiparam->side >= 1) { // 1 or 2
kx = kx0, ky = ky0;
MovePoint(&kx, &ky, norm + (right_ort? 180 : 0), equiparam->radRight);
LineSeg(kx0, ky0, kx, ky, EQUI_STYLE);
}
}
}
::ClearArray(pointArr);
::DeleteArray(pointArr);
}
int CSewingDlg::CheckContourSide(reference contour, bool swapped, bool issingle)
{
// if (m_StockOutCheck != 0 && m_StockInCheck != 0) return 2;
if (contour)
{
int type = GetObjParam(contour, 0, 0, ALLPARAM);
double t1, t2, x1, y1, x2, y2;
double perimeter = ksGetCurvePerimeter (contour, ST_MIX_MM);
ksGetCurveMinMaxParametr (contour, &t1, &t2);
ksGetCurvePoint(contour, t1, &x1, &y1);
ksGetCurvePoint(contour, t2, &x2, &y2);
if (ksIsCurveClosed(contour) == 0 && equal_points(x1, y1, x2, y2) == false)
Message("Equidistant: ERROR build contour - CURVE not closed!");
reference tmp_ref = 0;
if (issingle && type != CONTOUR_OBJ) {
Contour(1);
reference robj = Draw2DElement(contour, true);
tmp_ref = EndObj();
if (robj) DeleteObj(robj);
if (tmp_ref) contour = tmp_ref;
}
const int idiv = 5;
double step = (t2 - t1) / idiv;
double t = t1;
int inside = 0;
for (int i = 0; i < idiv; i++, t += step)
{
#if defined(DO_DEBUG)
//::Message("entering CheckIntersections");
#endif
inside = CheckIntersections(contour, swapped, t);
char buf[128];
::sprintf(buf, "координаты %d-й точки : %d", i, inside);
//::Message(buf);
if (inside == 3) break;
if (inside == 1) break;
}
if (tmp_ref) DeleteObj(tmp_ref);
//if (inside == 1) return (m_StockOutCheck != 0)? 1 : 0; // left side or both!
//if (inside == 3) return (m_StockOutCheck != 0)? 0 : 1; // right side or both!
return inside;
}
return 0;
}
int CSewingDlg::CheckIntersections(reference contour, bool swapped, double t)
{
double kx, ky, norm;
ksGetCurvePoint(contour, t, &kx, &ky);
double kx0 = kx, ky0 = ky;
norm = ksGetCurvePerpendicular(contour, kx, ky);
int ret = 0;
//MovePoint(&kx, &ky, norm, 1);
reference norm_line = Line(kx, ky, norm);
reference intersections = ::CreateArray(POINT_ARR, 0); // создать пустой массив точек пересечения
if (::ksIntersectCurvCurv(norm_line, contour, intersections) > 0)
{
int count = ::GetArrayCount(intersections); // количество элементов в массиве
MathPointParam par;
double dist = -1.0;
for (int i = 0; i < count; i++)
{
if (!::GetArrayItem(intersections, i, &par, sizeof(MathPointParam))) continue;
if (!equal_points(kx0, ky0, par.x, par.y)) {
double test_dist = DistancePntPnt(kx0, ky0, par.x, par.y);
if (dist <= 0.0) kx = par.x, ky = par.y, dist = test_dist;
else if (test_dist < dist) kx = par.x, ky = par.y, dist = test_dist;
}
}
const double kxmid = (kx + kx0) / 2, kymid = (ky + ky0) / 2;
double ort = 0.1, kxort = kxmid, kyort = kymid;
if (dist > 0.0) ::ksGetCurvePointProjection (contour, kxort, kyort, &kxort, &kyort);
int type = GetObjParam(contour, 0, 0, ALLPARAM);
int side = 0;
if (dist <= 0.0) side = 2;
else if (DistancePntPnt(kxmid, kymid, kxort, kyort) < ort * m_MmToUnits) side = 2;
else if (type != RECTANGLE_OBJ && type != REGULARPOLYGON_OBJ)
side = ksIsPointInsideContour(contour, kxmid, kymid, 1e-6);
else { // special cases
if (type == RECTANGLE_OBJ) {
RectangleParam rpRectangleParam;
if (GetObjParam(contour, &rpRectangleParam, sizeof(RectangleParam), ALLPARAM))
{
double x = rpRectangleParam.x,
y = rpRectangleParam.y;
double angle = rpRectangleParam.ang;
double w = rpRectangleParam.width,
h = rpRectangleParam.height;
side = 3;
}
}
if (type == REGULARPOLYGON_OBJ) {
RegularPolygonParam rppRegularPolygonParam;
if (GetObjParam(contour, &rppRegularPolygonParam, sizeof(RegularPolygonParam), ALLPARAM))
{
double xc = rppRegularPolygonParam.xc,
yc = rppRegularPolygonParam.yc;
double angle = rppRegularPolygonParam.ang;
double r = rppRegularPolygonParam.radius;
int sides = rppRegularPolygonParam.count;
int inscribed = rppRegularPolygonParam.describe;
r = (inscribed == 0)? r/2 : r;
side = (DistancePntPnt(xc, yc, kxmid, kymid) < r)? 3 : 1;
}
}
}
/* MovePoint(&kx0, &ky0, norm, dist);
if (equal_points(kx, ky, kx0, ky0)) ret = side;
else ret = (side == 1)? 3 : (side == 3)? 1 : side;*/
double tx = kx0, ty = ky0;
int dir = swapped? -1 : 1;
if (ksMovePointOnCurve (contour, &tx, &ty, 0.01, dir))
{
bool right_ort = 0 <= ( (kx - kx0) * (ty - ky0) - (tx - kx0) * (ky - ky0) );
#if defined(DO_DEBUG)
//if (right_ort)
//::Message("CheckIntersections : right_ort == true");
//else
//::Message("CheckIntersections : right_ort == false");
#endif
if (!right_ort) side = (side == 1)? 3 : (side == 3)? 1 : side;
//right = right_ort;
}
ret = side;
}
::ClearArray(intersections);
::DeleteArray(intersections);
if (norm_line) DeleteObj(norm_line);
return ret;
}
reference CSewingDlg::DestroyContoursGroup(int tipSearch)
{
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document (for KAPI5 usage)
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
if (!doc7) { Message("No document open - destroy"); return 0; }
//return 0;
std::vector<reference> locContours; // destroyed from CONTOUR_OBJ
do {
KompasIteratorHolder contour_iterator(CreateIterator(tipSearch, 0));
reference cur_obj_reference = MoveIterator(contour_iterator, 'F');
while (cur_obj_reference)
{
int type = GetObjParam(cur_obj_reference, 0, 0, ALLPARAM);
if (type != 0 && IsGeomObject( cur_obj_reference ) && (type == CONTOUR_OBJ)) // ONLY for CONTOURs!
{
//if (!ksIsCurveClosed(cur_obj_reference)) // !only not closed (skip singletons)
locContours.push_back(cur_obj_reference);
}
cur_obj_reference = MoveIterator(contour_iterator, 'N');
}
} while (0);
if (locContours.size() == 0) return 0;
reference a_group = 0, n_group = 0;
// Creating doc for building of nurbs approximation
DocumentParamT parDocument;
memset( &parDocument, 0, sizeof( parDocument ) );
parDocument.regim = 1; // hidden mode
parDocument.type = 3;
reference tmp_doc = CreateDocumentT( &parDocument ); // fragment creation
IKompasDocumentPtr tmp_doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
doc7->Application->ActiveDocument = doc7;
n_group = NewGroup(0);
EndGroup();
a_group = NewGroup(1);
EndGroup();
reference n_group0 = 0;
for (int i = 0; i < (int)locContours.size(); i++)
{
//locContours[i] = ksCopyObj(locContours[i],0,0,0,0,1,0);
AddObjGroup(a_group, locContours[i]);
//int iii = ExistGroupObj(a_group);
if (a_group && ExistGroupObj(a_group))
{
doc7->Application->ActiveDocument = tmp_doc7;
reference b_group = CopyGroupToDocument(a_group, m_pKompasDoc5->reference, tmp_doc);
StoreTmpGroup( b_group );
ksDestroyObjects(b_group);
if (b_group) DeleteObj(b_group);
reference c_group = NewGroup(1);
EndGroup();
SelectGroup(c_group, 2, 0,0,0,0);
if (ExistGroupObj(c_group))
{
n_group0 = CopyGroupToDocument(c_group, tmp_doc, m_pKompasDoc5->reference);
//ClearGroup(c_group); - ! WRONG : this clears the group and DeleteObj(c_group) DOESN'T delete any objects!
}
if (c_group) DeleteObj(c_group);
//doc7->Active = TRUE;
doc7->Application->ActiveDocument = doc7;
if (!n_group0) continue;
StoreTmpGroup( n_group0 );
do {
KompasIteratorHolder contour_iterator(CreateIterator(ALL_OBJ, n_group0));
reference cur_obj = MoveIterator(contour_iterator, 'F');
while (cur_obj)
{
int type = GetObjParam(cur_obj, 0, 0, ALLPARAM);
m_CurveParts.insert(std::pair <reference, reference> (cur_obj, locContours[i]));
AddObjGroup(n_group, cur_obj);
cur_obj = MoveIterator(contour_iterator, 'N');
}
} while (0);
ClearGroup(n_group0);
}
ClearGroup(a_group);
}
if (tmp_doc) CloseDocument(tmp_doc);
DeleteObj(a_group);
if (n_group0) DeleteObj(n_group0);
if (!ExistGroupObj(n_group)) { DeleteObj(n_group); n_group = 0; }
return n_group;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// обработчики сообщений CSewingDlg
void CSewingDlg::api7test()
{
UpdateData(TRUE);
if (m_StockOutCheck == 0 && m_StockInCheck == 0) return;
sewing_object->ShowWindow(SW_HIDE);
EnableTaskAccess( 0 ); // Disable Kompas access
ksUndoContainer(true);
EquidistantParam equidParam;
memset(&equidParam, 0, sizeof(equidParam));
equidParam.side = m_StockOutCheck != 0 && m_StockInCheck != 0?
2 : m_StockOutCheck != 0? 1 : 0; // признак, с какой стороны строить эквидистанту
equidParam.cutMode = 0;//1; // тип обхода углов контура: 0-обход срезом, 1- обход дугой
equidParam.degState = 0; // флаг разрешения вырожденных сегментов эквидистанты:
// 0-вырожденные сегменты запрещены, 1-вырожденные сегменты разрешены
equidParam.radRight = std::max(0.0, m_StockOut); // радиус эквидистанты справа по направлению кривой
equidParam.radLeft = std::max(0.0, m_StockIn); // радиус эквидистанты слева
equidParam.radRight *= m_MmToUnits;
equidParam.radLeft *= m_MmToUnits;
equidParam.style = EQUI_STYLE; // 2; // тип линии
int tipSearch = SELECT_GROUP_OBJ; // : ALL_OBJ;
KompasIteratorHolder group_iterator(CreateIterator(tipSearch, 0));
reference cur_obj_reference = MoveIterator(group_iterator, 'F');
if (cur_obj_reference == 0) Message("Nothing selected");
else
{
/* while (cur_obj_reference)
{
equi_curves.clear();
int type = GetObjParam(cur_obj_reference, 0, 0, ALLPARAM);
if (type != 0 && IsGeomObject( cur_obj_reference ))
{
equi_curves_count = 1;
equi_curves.push_back(cur_obj_reference);
equidParam.geoObj = cur_obj_reference;
DrawEquidistant(&equidParam, false);
equi_curves.clear();
}
cur_obj_reference = MoveIterator(group_iterator, 'N');
}*/
equi_curves.clear();
equi_curves_count = 0;
while (cur_obj_reference)
{
int type = GetObjParam(cur_obj_reference, 0, 0, ALLPARAM);
if (type != 0 && IsGeomObject( cur_obj_reference ))
{
equi_curves.push_back(cur_obj_reference);
equi_curves_count++;
}
cur_obj_reference = MoveIterator(group_iterator, 'N');
}
IKompasDocumentPtr doc7 = newKompasAPI->ActiveDocument; // ksTransferReference( m_pKompasDoc5->reference, 0 );
IKompasDocument2DPtr pkdDocument = 0;
doc7->QueryInterface(&pkdDocument);
IViewPtr ivpView = pkdDocument->ViewsAndLayersManager->Views->View[0];
IDrawingContainerPtr pdcContainer = 0;
ivpView->QueryInterface(&pdcContainer);
IDrawingContoursPtr idcContours = pdcContainer->DrawingContours;
IDrawingContourPtr idcContour = 0;
IContourPtr pContour = 0;
idcContour = idcContours->Add();
idcContour->QueryInterface(&pContour);
IMath2DPtr mathp = newKompasAPI->Application->Math2D;
int contour_count = pContour->Count;
//ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D();
double t1, t2;
double x1, y1, x2, y2;
ksGetCurveMinMaxParametr (equi_curves[0], &t1, &t2);
ksGetCurvePoint(equi_curves[0], t1, &x1, &y1);
ksGetCurvePoint(equi_curves[0], t2, &x2, &y2);
m_BegPoint.x = x1, m_BegPoint.y = y1;
m_swapped = CheckSwapCurve(equi_curves[0]);
if (m_swapped) m_BegPoint.x = x2, m_BegPoint.y = y2;
//m_pKompasDoc5->ksContour(1);
for (int i = 0; i < equi_curves.size(); i++)
{
//Contour(1);
reference obj = 0;
reference curve = equi_curves[i];
//obj = Draw2DElement(equi_curves[i]);
int type = GetObjParam(curve, 0, 0, ALLPARAM);
if (type != 0 && IsGeomObject( curve ))
{
// IContourSegmentPtr icsSegment = 0;
//ICurve2DPtr temp_curve = 0;
Message("case ELLIPSE_ARC_OBJ:");
reference obj = Draw2DElement(curve);
IDrawingObjectPtr pCurve = obj? ksTransferReference(obj, 0) : 0;
if (pCurve) pContour->CopyCurve(pCurve, FALSE);
contour_count = pContour->Count;
IContourSegmentPtr icsSegment = pContour->Segment[0];
if (obj) DeleteObj(obj);
}
}
if (contour_count > 0)
{
idcContour->Update();
PumpWaitingMessages();
}
//reference ref = m_pKompasDoc5->ksEndObj();
reference ref = idcContour->Reference;
if (ref == 0) ref = pContour->Reference;
/*equidParam.geoObj = ref;
DrawEquidistant(&equidParam, m_swapped);
if (ref) DeleteObj(ref);*/
//if (ref == 0)
{
IEquidistantsPtr Equidistant_pool = pdcContainer->Equidistants;
IEquidistantPtr Equidistant_curve = Equidistant_pool->Add();
IDrawingObjectPtr drawing_object = idcContour;
BOOL isok = false;
BOOL test_isok = false;
do {
Equidistant_curve->BaseObject = drawing_object;
Equidistant_curve->CutMode = equidParam.cutMode == 0? FALSE : TRUE;
Equidistant_curve->DegenerateSegment = equidParam.degState == 0? FALSE : TRUE;
Equidistant_curve->LeftRadius = equidParam.radLeft;
Equidistant_curve->RightRadius = equidParam.radRight;
Equidistant_curve->Side = equidParam.side == 2? ksETBoth :
equidParam.side == 0? ksETLeft : equidParam.side == 1? ksETRight : ksETUnknown;
Equidistant_curve->Style = equidParam.style;
isok = Equidistant_curve->Update();
//if (!isok)
// for (int i = 0; i < 10; i++) { PumpWaitingMessages(); isok = Equidistant_curve->Update(); if (isok) break; }
//Message("Bad Equi->Update()");
//pdoDrawingObject->LayerNumber = pdoDrawingObject->LayerNumber;
//if (!pdoDrawingObject->Update()) Message("NO update");
if (!isok) {
Equidistant_curve->DegenerateSegment = TRUE;
//Equidistant_curve->CutMode = TRUE;
}
isok = isok || test_isok;
test_isok = true;
} while (!isok);
ref = Equidistant_curve->Reference;
}
if (idcContour) idcContour->Delete();
equi_curves.clear();
equi_curves_count = 0;
}
EnableTaskAccess( 1 ); // Enable Kompas access
ksExecuteKompasCommand(ksCMRefresh, 1);
}
void CSewingDlg::OnBnClickedDrawOperation()
{
//return api7test();
UpdateData(TRUE);
if (m_StockOutCheck == 0 && m_StockInCheck == 0) return;
sewing_object->ShowWindow(SW_HIDE);
EnableTaskAccess( 0 ); // Disable Kompas access
ksUndoContainer(true);
// IKompasDocumentPtr m_pKompasDoc7; // Current Kompas document (for KAPI7/KAPI5 usage)
ksDocument2DPtr m_pKompasDoc5 = kompasAPI->ActiveDocument2D(); // Current Kompas document (for KAPI5 usage)
m_CurveParts.clear();
int tipSearch = (m_SelectType == enCurves_All)? ALL_OBJ_SHOW_ORDER :
(m_SelectType == enCurves_Selected)? SELECT_GROUP_OBJ : ALL_OBJ;
reference ex_group = CSewingDlg::DestroyContoursGroup(tipSearch);
std::vector<reference> locApproxedGroups;
if (m_SelectType == enCurves_Selected)
AddObjGroup(0, ex_group); // выделение!
do {
KompasIteratorHolder all_iterator(CreateIterator(tipSearch, 0));
std::vector<reference> locApproxedCurves;
reference cur_obj_reference = MoveIterator(all_iterator, 'F');
while (cur_obj_reference)
{
int type = GetObjParam(cur_obj_reference, 0, 0, ALLPARAM);
if (type != 0 && IsGeomObject( cur_obj_reference )
&& (type == CONTOUR_OBJ))//?? || type == BEZIER_OBJ)) // || type == NURBS_OBJ))
{
if (type != CONTOUR_OBJ)
locApproxedCurves.push_back(cur_obj_reference);
}
cur_obj_reference = MoveIterator(all_iterator, 'N');
}
for (int i = 0; i < (int)locApproxedCurves.size(); i++) {
int type = GetObjParam(locApproxedCurves[i], 0, 0, ALLPARAM);
reference tmp_grp = DrawApproximation(locApproxedCurves[i], type);
if (tmp_grp && ExistGroupObj(tmp_grp))
{
locApproxedGroups.push_back( tmp_grp );
do {
KompasIteratorHolder contour_iterator(CreateIterator(ALL_OBJ, tmp_grp));
reference cur_obj = MoveIterator(contour_iterator, 'F');
while (cur_obj)
{
int type = GetObjParam(cur_obj, 0, 0, ALLPARAM);
m_CurveParts.insert(std::pair <reference, reference> (cur_obj, locApproxedCurves[i]));
cur_obj = MoveIterator(contour_iterator, 'N');
}
} while (0);
if (m_SelectType == enCurves_Selected)
AddObjGroup(0, tmp_grp); // выделение!
}
}
} while (0);
EquidistantParam equidParam;
memset(&equidParam, 0, sizeof(equidParam));
// equidParam.geoObj = obj; //-базовая кривая эквидистанты
equidParam.side = m_StockOutCheck != 0 && m_StockInCheck != 0?
2 : m_StockOutCheck != 0? 1 : 0; // признак, с какой стороны строить эквидистанту
equidParam.cutMode = 0;//1; // тип обхода углов контура: 0-обход срезом, 1- обход дугой
equidParam.degState = 0; // флаг разрешения вырожденных сегментов эквидистанты:
// 0-вырожденные сегменты запрещены, 1-вырожденные сегменты разрешены
equidParam.radRight = std::max(0.0, m_StockOut); // радиус эквидистанты справа по направлению кривой
equidParam.radLeft = std::max(0.0, m_StockIn); // радиус эквидистанты слева
equidParam.radRight *= m_MmToUnits;
equidParam.radLeft *= m_MmToUnits;
equidParam.style = EQUI_STYLE; // 2; // тип линии
KompasIteratorHolder group_iterator(CreateIterator(tipSearch, 0));
PrepareContoursMakeEquidistants(group_iterator, &equidParam);
for (int i = 0; i < (int)locApproxedGroups.size(); i++) DeleteObj(locApproxedGroups[i]);
if (ex_group) {
//if (ExistGroupObj(ex_group)) ClearGroup(ex_group); // SKIP THIS to delete STORED group!
DeleteObj(ex_group);
}
m_CurveParts.clear();
ksUndoContainer(false);
RefreshKompasActiveDocument();
m_UndoRedo = 0;
EnableTaskAccess( 1 ); // Enable Kompas access
((CButton*)GetDlgItem( IDC_UNDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditUndo) != 0 );
((CButton*)GetDlgItem( IDC_REDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditRedo) != 0 );
sewing_object->ShowWindow(SW_NORMAL);
sewing_object->SetActiveWindow();
ksExecuteKompasCommand(ksCMRefresh, 1);
}
void CSewingDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
// MessageBox(L"OnKeyDown");
}
extern void DrawRectNULL();
extern void DrawRectCallBack();
void CSewingDlg::OnBnClickedCancel()
{
if (stateManualDrawMarks == FALSE)
return OnCancel();
stateManualDrawMarks = FALSE;
((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->SetWindowTextW( L"Ввод засечек" );
((CButton*)GetDlgItem( IDC_DATAEDIT ))->ShowWindow(SW_HIDE);
((CButton*)GetDlgItem( IDC_STATIC ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STATIC2 ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STATIC3 ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STATIC4 ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STATIC5 ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STOCKOUT ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_STOCKIN ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_MARKING ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_MARKS_PER_CURVE ))->ShowWindow(SW_SHOWNOACTIVATE);
((CButton*)GetDlgItem( IDC_CURVE_MAX_POINTS ))->ShowWindow(SW_SHOWNOACTIVATE);
}
void CSewingDlg::OnBnClickedManualMarks()
{
//bool res = sewing_object->ShowWindow(SW_HIDE) != FALSE; // Show dialog
IDispatchPtr doc = kompasAPI->ksGetDocumentByReference(0);
//if (1)
if ( !BaseEvent::FindEvent( DIID_ksDocumentFileNotify, doc ) )
{
// Advising to Document etc. Events - DOESNT advise DocumentFrameEvent!
AdviseDoc( kompasAPI, doc, kompasAPI->ksGetDocumentType( 0 ) );
}
//((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->EnableWindow( 0 );
stateManualDrawMarks = stateManualDrawMarks == FALSE? TRUE : FALSE;
if (stateManualDrawMarks == TRUE)
((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->SetWindowTextW( L"Сброс режима" );
else
((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->SetWindowTextW( L"Ввод засечек" );
((CButton*)GetDlgItem( IDC_STATIC ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STATIC2 ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STATIC3 ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STATIC4 ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STATIC5 ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STOCKOUT ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_STOCKIN ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_MARKING ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_MARKS_PER_CURVE ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_CURVE_MAX_POINTS ))->ShowWindow(stateManualDrawMarks == FALSE? SW_SHOWNOACTIVATE : SW_HIDE);
((CButton*)GetDlgItem( IDC_DATAEDIT ))->ShowWindow(stateManualDrawMarks == TRUE? SW_SHOWNOACTIVATE : SW_HIDE);
//DrawRectNULL();
if (0)
DrawRectCallBack();
if (0) {
//void CommandWindow_Example (void)
RequestInfo info;
memset(&info, 0, sizeof(info));
info.commands = "!Окружность !Отрезок ";
info.title = "Объекты";
int j=CommandWindow(&info);
switch (j) {
case 1:
Circle(10,10,10,1);
break;
case 2:
LineSeg(10,10, 20, 10, 1);
break;
}
} // CommandWindow_Example
//res = (sewing_object->ShowWindow(SW_NORMAL) != FALSE); // Show dialog
}
void CSewingDlg::OnBnClickedUndo()
{
//bool res = sewing_object->ShowWindow(SW_HIDE) != FALSE; // Show dialog
int cUndoRedo = ksCMEditUndo; // m_UndoRedo == 0? ksCMEditUndo : ksCMEditRedo;
//m_UndoRedo = m_UndoRedo == 0? 1 : 0;
m_UndoRedo += 1;
ksExecuteKompasCommand(cUndoRedo, 0);
RefreshKompasActiveDocument();
((CButton*)GetDlgItem( IDC_UNDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditUndo) != 0 );
((CButton*)GetDlgItem( IDC_REDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditRedo) != 0 );
ksExecuteKompasCommand(ksCMRefresh, 1);
}
void CSewingDlg::OnBnClickedRedo()
{
int cUndoRedo = ksCMEditRedo; // m_UndoRedo == 0? ksCMEditUndo : ksCMEditRedo;
m_UndoRedo -= 1;
ksExecuteKompasCommand(cUndoRedo, 0);
RefreshKompasActiveDocument();
((CButton*)GetDlgItem( IDC_UNDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditUndo) != 0 );
((CButton*)GetDlgItem( IDC_REDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditRedo) != 0 );
ksExecuteKompasCommand(ksCMRefresh, 1);
}
void CSewingDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
if (nState == WA_INACTIVE) return;
int doctype = ksGetDocumentType(0);
int dd1 = kompasAPI->ksGetDocumentType(0);
IKompasDocumentPtr ppp = (IKompasDocumentPtr)kompasAPI->ksGetDocumentByReference(0);
int ddd2 = ppp? ppp->DocumentType : 0;
//if (doctype == 0) return;
if (doctype == 0 ||
(doctype != lt_DocSheetStandart && doctype != lt_DocSheetUser && doctype != lt_DocFragment))
{
bool actitest = ((CButton*)GetDlgItem( IDC_DRAW_OPERATION ))->IsWindowEnabled() != FALSE;
((CButton*)GetDlgItem( IDC_DRAW_OPERATION ))->EnableWindow( 0 );
((CButton*)GetDlgItem( IDC_UNDO ))->EnableWindow( 0 );
((CButton*)GetDlgItem( IDC_REDO ))->EnableWindow( 0 );
((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->EnableWindow( 0 );
if (actitest) // || doctype == 0)
Message("Активный документ не является чертежом или фрагментом или не открыто никакого документа."
"\nПлагин будет отключен до перехода к поддерживаемому типу документа.");
}
else
{
((CButton*)GetDlgItem( IDC_DRAW_OPERATION ))->EnableWindow( 1 );
((CButton*)GetDlgItem( IDC_UNDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditUndo) != 0 );
((CButton*)GetDlgItem( IDC_REDO ))->EnableWindow( ksIsKompasCommandEnable(ksCMEditRedo) != 0 );
((CButton*)GetDlgItem( IDC_MANUAL_MARKS ))->EnableWindow( 1 );
//((CEdit*)GetDlgItem( IDC_DATAEDIT ))->GetWindowTextLengthW() == 0? 1 : 0 );
short unittype = 0;
if (GetDocOptions(LENGTHUNITS_OPTIONS, &unittype, sizeof(unittype)))
m_MmToUnits = (unittype == ST_MIX_MM)? 1.0 : (unittype == ST_MIX_SM)? 0.1 :
(unittype == ST_MIX_DM)? 0.01 : (unittype == ST_MIX_M)? 0.001 : 1.0;
MmToUnits = m_MmToUnits;
}
}
void CSewingDlg::ParseDoubleData(int nID)
{
CEdit* ctrl_item = (CEdit*)sewing_object->GetDlgItem(nID);
CString text;
ctrl_item->GetWindowTextW(text);
int chindex = text.Find('.');
if (chindex >= 0) {
chindex = text.Find('.', chindex + 1);
if (chindex >= 0) ctrl_item->SetWindowTextW(text.Left(chindex));
}
if (ctrl_item->GetWindowTextLengthW() == 1 && text.Find('.') >= 0) ctrl_item->SetWindowTextW(_T(""));
if (ctrl_item->GetWindowTextLengthW() == 0) ctrl_item->SetWindowTextW(_T("0"));
}
void CSewingDlg::OnEnKillfocusStockout()
{
ParseDoubleData(IDC_STOCKOUT);
}
void CSewingDlg::OnEnKillfocusStockin()
{
ParseDoubleData(IDC_STOCKIN);
}
void CSewingDlg::OnEnKillfocusMarking()
{
ParseDoubleData(IDC_MARKING);
}
void CSewingDlg::OnEnKillfocusPrecision()
{
ParseDoubleData(IDC_PRECISION);
}
void CSewingDlg::OnEnChangeMarking()
{
// TODO: Если это элемент управления RICHEDIT, то элемент управления не будет
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Добавьте код элемента управления
}